JAVA之旅(二十五)——文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine
我们继续IO上个篇幅讲
一.文本复制
读写都说了,我们来看下其他的操作,我们首先来看复制
- 复制原理:其实就是将C盘下的文件数据存储到D盘的一个文件中
实现的步骤:
1.在D盘创建一个文件,用于存储文件中的数据
2.定义读取流和文件关联
3.通过不断的读写完成数据的存储
关闭资源
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 1package com.lgl.hellojava;
2
3import java.io.FileReader;
4import java.io.FileWriter;
5import java.io.IOException;
6
7public class HelloJJAVA {
8 public static void main(String[] args) {
9
10 copy_1();
11 copy_2();
12 }
13
14 // 从c盘读一个字符,就往D盘写一个字符
15 public static void copy_1() {
16 try {
17 // 创建目的地
18 FileWriter fw = new FileWriter("copy_1.txt");
19 // 与已有文件关联
20 FileReader fr = new FileReader("copy_1.txt");
21 int ch = 0;
22 while ((ch = fr.read()) != -1) {
23 // 读一个 写一个
24 fw.write(ch);
25 }
26 fw.close();
27 fr.close();
28 } catch (IOException e) {
29 // TODO Auto-generated catch block
30 e.printStackTrace();
31 }
32 }
33
34 public static void copy_2() {
35 FileWriter fw = null;
36 FileReader fr = null;
37
38 try {
39 fw = new FileWriter("copy_2.txt");
40 fr = new FileReader("copy_2.txt");
41
42 char[] buf = new char[1024];
43
44 int len = 0;
45 while ((len = fr.read(buf)) != -1) {
46 fw.write(buf, 0, len);
47 }
48 } catch (IOException e) {
49 // TODO Auto-generated catch block
50 e.printStackTrace();
51 } finally {
52 if (fr != null) {
53 try {
54 fr.close();
55 } catch (IOException e) {
56 // TODO Auto-generated catch block
57 e.printStackTrace();
58 }
59 }
60
61 if (fw != null) {
62 try {
63 fw.close();
64 } catch (IOException e) {
65 // TODO Auto-generated catch block
66 e.printStackTrace();
67 }
68 }
69 }
70 }
71}
72
73
这里做了两种方式的拷贝方式,其实都是整理好思路,读和写的一个过程罢了!
二.字符流的缓冲区
字符流的缓冲区,提高了对数据的读写效率,他有两个子类
- BufferedWriter
- BufferedReader
缓冲区要结合柳才可以使用
在流的基础上对流的功能进行了增强
1.BufferedWriter
缓冲区的出现是提高流的效率而出现的,所以在创建缓冲区之前,必须先有流对象,我们看例子
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 1package com.lgl.hellojava;
2
3import java.io.BufferedWriter;
4import java.io.FileWriter;
5import java.io.IOException;
6
7public class HelloJJAVA {
8 public static void main(String[] args) {
9
10 try {
11 // 创建一个字符写入流对象
12 FileWriter fw = new FileWriter("buffer.txt");
13 // 为了提高写入流的效率加入了缓冲技术
14 BufferedWriter bufw = new BufferedWriter(fw);
15 //写入数据
16 bufw.write("hello");
17 //换行
18 bufw.newLine();
19
20 //只要用到了缓冲区,就需要刷新
21 bufw.flush();
22
23 //缓冲区关闭的就是关联的流
24 bufw.close();
25
26 } catch (IOException e) {
27 // TODO Auto-generated catch block
28 e.printStackTrace();
29 }
30
31 }
32}
33
34
使用都是比较基础的,大家也是可以看到
2.BufferedReader
高效读取
我们直接看代码
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 1package com.lgl.hellojava;
2
3import java.io.BufferedReader;
4import java.io.FileNotFoundException;
5import java.io.FileReader;
6import java.io.IOException;
7
8public class HelloJJAVA {
9 public static void main(String[] args) {
10
11 try {
12 // 创建一个读取流对象和文件相关联
13 FileReader fr = new FileReader("buffer.txt");
14 // 为了提高效率,加入缓冲技术
15 BufferedReader bfr = new BufferedReader(fr);
16
17 String line = null;
18 while((line = bfr.readLine()) != null){
19 System.out.println(line);
20 }
21 bfr.close();
22 } catch (FileNotFoundException e) {
23 // TODO Auto-generated catch block
24 e.printStackTrace();
25 } catch (IOException e) {
26 // TODO Auto-generated catch block
27 e.printStackTrace();
28 }
29
30 }
31}
32
33
这样就可以全部出来了
三.通过缓冲区复制文件
OK,我们还是复制文件这个问题,现在我们有缓冲区,我们要怎么样复制文件?
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
38
39
40
41 1package com.lgl.hellojava;
2
3import java.io.BufferedReader;
4import java.io.BufferedWriter;
5import java.io.FileNotFoundException;
6import java.io.FileReader;
7import java.io.FileWriter;
8import java.io.IOException;
9
10public class HelloJJAVA {
11 public static void main(String[] args) {
12 /**
13 * 缓冲区文件复制
14 */
15 BufferedReader bufr = null;
16 BufferedWriter bufw = null;
17
18 try {
19 bufr = new BufferedReader(new FileReader("buffer.txt"));
20 bufw = new BufferedWriter(new FileWriter("buffercopy.txt"));
21
22 String line = null;
23
24 while((line = bufr.readLine()) != null){
25 bufw.write(line);
26 }
27
28 //关闭流
29 bufr.close();
30 bufw.close();
31 } catch (FileNotFoundException e) {
32 // TODO Auto-generated catch block
33 e.printStackTrace();
34 } catch (IOException e) {
35 // TODO Auto-generated catch block
36 e.printStackTrace();
37 }
38 }
39}
40
41
这样,就可以复制文件了
四.readLine工作原理
我们注意到我们要使用这个方法readline,无论是读一行还是读多个字符,其实都是在硬盘上一个一个读取,所以最终使用的还是read方法一个读一个的方法
- 其实他内存中有一个数组,你读完之后并没有立马读,而是临时存储起来,这就是缓冲区,
当读到换行,才去返回一行数据,就这样一行一行的读取,这就是他的工作原理
五.自定义readLine
我们了解了readLine的工作原理,那我们就可以尝试去更改他了,自定义一个怎么样?我们尝试一下
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 1package com.lgl.hellojava;
2
3import java.io.FileNotFoundException;
4import java.io.FileReader;
5import java.io.IOException;
6
7public class HelloJJAVA {
8 public static void main(String[] args) {
9 /**
10 * 自定义readLine
11 */
12 FileReader fr;
13 try {
14 fr = new FileReader("buffer.txt");
15 MyBufferReader my = new MyBufferReader(fr);
16 String line = null;
17
18 while ((line = my.myReadLine()) != null) {
19 System.out.println(line);
20 }
21 } catch (FileNotFoundException e) {
22 // TODO Auto-generated catch block
23 e.printStackTrace();
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }
28
29 }
30}
31
32class MyBufferReader {
33
34 private FileReader fr;
35
36 public MyBufferReader(FileReader fr) {
37 this.fr = fr;
38 }
39
40 // 一次读取一行的方法
41 public String myReadLine() throws IOException {
42
43 // 定义临时容器
44 StringBuilder sb = new StringBuilder();
45 int ch = 0;
46 while ((ch = fr.read()) != -1) {
47
48 if (ch == '\r') {
49 continue;
50 } else if (ch == '\n') {
51 return sb.toString();
52 } else {
53 sb.append((char) ch);
54 }
55 }
56 if(sb.length() != 0){
57 return sb.toString();
58 }
59 return null;
60 }
61
62 public void close() throws IOException {
63 fr.close();
64 }
65}
66
67
仔细看实现思路,静静的看,没错,我们也是可以实现的,好的,我们本篇到这里也OK,算是结束了,我们下一篇继续会将IO的,毕竟这是一个大知识点!