JAVA之旅(二十七)——字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律
我们继续来聊聊I/O
一.字节流的缓冲区
这个,和我们的字符流基本上没有什么差别,我们来拷贝mp3,看例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 1// 通过字节流的缓冲区拷贝图片
2 public static void copyMp3() {
3
4 try {
5 FileInputStream fi = new FileInputStream("audio.mp3");
6 BufferedInputStream buf = new BufferedInputStream(fi);
7
8 FileOutputStream fio = new FileOutputStream("audioCapy.mp3");
9 BufferedOutputStream buo = new BufferedOutputStream(fio);
10
11 int ch = 0;
12
13 while ((ch = buf.read()) != -1) {
14 buo.write(ch);
15 }
16
17 buf.close();
18 buo.close();
19 } catch (FileNotFoundException e) {
20 // TODO Auto-generated catch block
21 e.printStackTrace();
22 } catch (IOException e) {
23 // TODO Auto-generated catch block
24 e.printStackTrace();
25 }
26 }
27
这样,就直接拷贝了
二.自定义字节流缓冲区
我们队缓冲区已经了解很多了,这样的话,我们来尝试解析他的原理然后自定义一个字节流的缓冲区出来,来看看对不对
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 1class MyBufferedImputStream {
2
3 private InputStream in;
4 private byte[] buf = new byte[1024];
5 private int pos = 0;
6 private int count = 0;
7
8 public MyBufferedImputStream(InputStream in) {
9 this.in = in;
10 }
11
12 // 从缓冲区一次读一个字节
13 public int myRead() throws IOException {
14 // 通过in对象读取硬盘上的数据,存储在buf
15 if (count == 0) {
16 count = in.read(buf);
17 if (count < 0)
18 return -1;
19 byte b = buf[pos];
20 count--;
21 pos++;
22 return b;
23 } else if (count > 0) {
24 byte b = buf[pos];
25 pos++;
26 count--;
27 return b;
28 }
29 return -1;
30 }
31 //关闭流
32 public void myClose() throws IOException {
33 in.close();
34 }
35}
36
37
思路是比较清晰的,想知道对不对,小伙伴赶紧去试试
三.读取键盘录入
这个其实早就要讲,现在讲就有点晚了,就是键盘输入文字读取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 1package com.lgl.hellojava;
2
3import java.io.IOException;
4import java.io.InputStream;
5
6public class HelloJJAVA {
7 public static void main(String[] args) throws IOException {
8 /**
9 * 通过键盘录入数据 当录入一行数据后,打印 发现over,停止
10 */
11 InputStream in = System.in;
12 StringBuilder sb = new StringBuilder();
13 while (true) {
14 int ch = in.read();
15 if (ch == '\r')
16 continue;
17 if (ch == '\n') {
18 String s = sb.toString();
19 if ("over".equals(s))
20 break;
21 System.out.println(s);
22 // delte all
23 sb.delete(0, sb.length());
24 } else
25 sb.append(ch);
26
27 }
28 }
29}
30
31
当我们写完之后就发现,这个写法我们之前是有写过的,就是readLine的原理,这样的话,我们可以对其进行改造一下,但是这里就产生了一个新的问题,一个是字符流,一个是字节流,那这里也就产生了一个思考,能不能将字节流转换成字符流,再去使用它缓冲区的readLine方法呢?
四.转换流InputStreamReader
java中需要转换流就会使用到转换流,使用到了InputStreamReader,你会发现十分的方便的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 1package com.lgl.hellojava;
2
3import java.io.BufferedReader;
4import java.io.IOException;
5import java.io.InputStream;
6import java.io.InputStreamReader;
7
8public class HelloJJAVA {
9 public static void main(String[] args) throws IOException {
10 //获取键盘录入对象
11 InputStream in = System.in;
12 //转换
13 InputStreamReader isr = new InputStreamReader(in);
14 //提高效率
15 BufferedReader bur = new BufferedReader(isr);
16 String line = null;
17 while((line = bur.readLine()) != null){
18 if(line.equals("over"))
19 break;
20 System.out.println(line.toString());
21 }
22 }
23}
24
25
我们来演示一下
五.写入转换流
我们转换流的read学完了,我们就来学习一下write.我们继续增强上面的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 1package com.lgl.hellojava;
2
3import java.io.BufferedReader;
4import java.io.BufferedWriter;
5import java.io.IOException;
6import java.io.InputStream;
7import java.io.InputStreamReader;
8import java.io.OutputStream;
9import java.io.OutputStreamWriter;
10
11public class HelloJJAVA {
12 public static void main(String[] args) throws IOException {
13 //获取键盘录入对象
14 InputStream in = System.in;
15 //转换
16 InputStreamReader isr = new InputStreamReader(in);
17 //提高效率
18 BufferedReader bur = new BufferedReader(isr);
19
20 OutputStream os = System.out;
21 OutputStreamWriter osw = new OutputStreamWriter(os);
22 BufferedWriter bufw = new BufferedWriter(osw);
23
24
25 String line = null;
26 while((line = bur.readLine()) != null){
27 if(line.equals("over"))
28 break;
29 bufw.write(line.toString());
30 bufw.newLine();
31 bufw.flush();
32 }
33 }
34}
35
36
OK,实现的功能也是正常的了;
六.流操作的规律
我们写了这么多流,我们来总结一下规律
-
1
-
源:键盘录入
- 目的:控制台
-
2 : 需求:想把键盘录入的数据存储到一个文件中
-
源:键盘
- 目的:文件
-
3.需求:想要将一个文件的数据打印在控制台上
-
源:文件
- 目的:控制台
流操作的基本规律
-
最痛苦的就是不知道流对象要用哪一个
-
通过两个明确来完成
-
1.明确源和目的
-
源:输入流 InputStream Reader
* 目的:输出流 OutputStream writer- 2.明确操作的数据是否是纯文本
-
是:字符流
* 不是:字节流- 3.当体系明确后,再明确要使用哪个具体的对象
-
通过设备来进行区分
* 源设备:内存,硬盘,键盘
* 目的:内存,硬盘,控制台。
前面两个是比较重要的,也可以明确出来,第三个就是加分项了
I/O就先到这里了,我们下篇继续聊,同时开始讲File了