自定义readLine方法,模拟实现其功能
1: import java.io.*;
2: class MyBufferedReader
3: {
4: private FileReader r;
5: //构造函数接受一个文件读取流对象传给本类
6: MyBufferedReader (FileReader r)
7: {
8: this.r = r;
9: }
10: public String myReadLine() throws IOException
11: {
12: //新建一个字符容器用于存放读取到的单个字符
13: StringBuilder sb = new StringBuilder ();
14: int ch = 0;
15: //以全文是否结束为 停止读取的条件
16: while ((ch = r.read()) != -1)
17: {
18: if (ch == '\r')
19: continue;
20: //读取到文本中的回车符时,表示一行读取完毕,将容器内的字符转成字符串返回给调用者
21: if(ch == '\n')
22: return sb.toString();
23:
24: //只要没到行末尾,就不停的把读取到的字符加入容器中
25: else
26: sb.append((char)ch);
27: }
28: //到了最后一行时,只要读到的行不为空,就把所有内容返回
29: if (sb.length() != 0)
30: return sb.toString();
31:
32: //若最后一行为空,则返回空。
33:
34: return null;
35: }
36: //关流,要写在外面,因为写在里面若前面return后就执行不到了
37: public final void myClose() throws IOException
38: {
39: r.close();
40: }
41: }
42: class MyBufferedReaderDemo2
43: {
44: public static void main(String[] args) throws IOException
45: {
46: //建立流关联要读取的文件
47: FileReader fr = new FileReader ("F:\\1.txt");
48:
49: MyBufferedReader mybf = new MyBufferedReader (fr);
50:
51: String line = null;
52: //把返回来的一行字符串赋给line,只要返回来的行值不为空就打印返回行内容。
53: while ((line = mybf.myReadLine()) != null)
54: {
55: System.out.println(line);
56: }
57: mybf.myClose();
58: }
59: }
自定义字节读取流缓冲区,模拟实现BufferedInputStream功能
用自定义的BufferedInputStream来实现复制mp3的操作
关于为什么b要与255
/*
* 全文结束后返回的标志-1,你函数定义的返回值类型是什么,-1就是什么类型的,
* 像这里,函数定义为int,那么全文结束标志-1返回的二进制形式就是32个1
* 那么为什么返回值用int而不是byte呢?
关于返回的int b占用的是32个二进制位,而mp3里的字节文件为8个二进制位
为什么不直接返回byte呢?因为循环读数时可能会从mp3字节中连续读到了8个1 ,
(1111 1111),那么b=-1;复制就结束了,但这个-1不是结尾标志值-1
所以b&一个int类型的数255,当读到8个1时,他提升为了255,就不会返回 -1了,穿上了一层伪装
不用担心写的时候出错,因为write方法写出的时候,自动给它脱衣服,变回原来的8个1
这样读完全文,返回一个int类型的-1,否则中途不会有见到8个1就返回的时候。
*/
1: package Itcast.com;
2: import java.io.*;
3: /**自定义字节流读取缓冲区
4: * @author shantui *
5: */
6:
7: public class MyBufferedInput
8: {
9: private FileInputStream in;
10: private byte[] buf=new byte [1024];
11: private int pos=0;
12: private int count=0;
13: //自定义读取流缓冲,传入已关联音频文件的流对象,将其传给本类
14: MyBufferedInput(FileInputStream in)
15: {
16: this.in=in;
17: }
18: //自定义往自己缓冲区里读入字节的方式,注意这里返回值类型是int,而不是byte,原因在函数末尾
19: public int myRead()throws IOException
20: {
21: //初始时count肯定是0
22: if(count==0)
23: {
24: //往字符数组buf里读入一批字节,记住读了多少个
25: count =in.read(buf);
26: //每抓一批新字节进数组前,指针都归零
27: pos =0;
28: //将字节数组中第pos个字符赋给b
29: byte b=buf[pos];
30: //赋值一次pos前移一位,计算读取个数的计数器减一
31: count--;
32: pos++;
33: //如过最后抓了空值进来,那么这里就结束了,count=-1了,把结束标记返回。
34: if (count<0)
35: return -1;
36: //只要不是空值,就把读到的b返回。
37: else
38: //返回第一个字符b
39: return b&255;
40: }
41: //以上主要是为了判断结尾,一边返回结束符,下面才是读取的主体:返回下一个字符b
42: else if(count>0)
43: {
44: //按照指针的移动,读取相应的字符
45: byte b=buf[pos];
46: count--;
47: pos++;
48: return b&255;
49: }
50: return -1;
51:
52: }
53: public void MyClose()throws IOException
54: {
55: in.close();
56: }
57: public static void main(String[] args)throws IOException
58: {
59: MyBufferedInput bufis=new MyBufferedInput (new FileInputStream("F:\\Listen.mp3"));
60: BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("D:\\yes.mp3"));
61: int bytes= 0;
62: //只要没读到结束标志字符,就循环的往下读取
63: try
64: {
65: while((bytes=bufis.myRead())!=-1)
66: {
67: //读一个就写到缓存里一个
68: bufos.write(bytes);
69: }
70: }
71: catch (IOException e)
72: {
73: throw new RuntimeException("复制音频失败");
74: }
75: finally
76: {
77: try
78: {
79: if(bufis!=null)
80: {
81: bufis.MyClose();
82: }
83: }
84: catch (IOException e)
85: {
86: throw new RuntimeException("读音频失败");
87: }
88: try
89: {
90: if(bufos!=null)
91: {
92: bufos.close();
93: }
94: }
95: catch (IOException e)
96: {
97: throw new RuntimeException("写音频失败");
98: }
99: }
100: }
101:
102:
103:
104:
105: }
Properties(hashtable)子类,为集合与IO相结合的类
用于存放配置信息,键值对信息
P.setProperty(a1,a2),a1自动视为键 ;a2自动视为值
FileInputStream fis =new FileInputStream(关联配置文件)
P.load(fis)=把配置文件内容装载到Properties集合中
P.list(System.out)列出 集合目录
打印流 PrintStream
可 直接操作文件、流(字节输出流)、字符串
最常用的字符打印流PrintWriter,可直接操作file、outputstream、writer
PrintStream
为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream
永远不会抛出 IOException
;而是,异常情况仅设置可通过 checkError
方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream
;这意味着可在写入 byte 数组之后自动调用 flush
方法,可调用其中一个 println
方法,或写入一个换行符或字节 ('\n'
)。