前言
众所周知,Java中有多种针对文件的操作类,以面向字节流和字符流可分为两大类,这里以写入为例:
面向字节流的:FileOutputStream 和 BufferedOutputStream
面向字符流的:FileWriter 和 BufferedWriter
近年来发展出New I/O ,也叫NIO,里面又包装了两个类:NewOutputStream 和 NewBufferedWriter
现在,我们建立测试程序,比较这些类写入文件的性能。
机器配置
- Processor Name: Intel Core i7
- Processor Speed: 2.2 GHz
- Number of Processors: 1
- Total Number of Cores: 4
- L2 Cache (per Core): 256 KB
- L3 Cache: 6 MB
- Memory: 16 GB
测试程序
纵向比较:几种文件操作类向文件中写入相同行数的内容(每行内容均为“写入文件Data\n”),比较其耗费时间
横向比较:对于同一个文件操作类,比较写入不同行数内容情况下所耗费时间;本文以2的次方指数级增长行数
1 import java.io.File;
2 import java.io.FileOutputStream;
3 import java.io.*;
4 import java.nio.file.Files;
5 import java.nio.file.Paths;
6
7 public class testFileIO {
8
9 public static void testDriver () throws IOException {
10 int maxlineNum = 100000001;//写入文件的最大行数
11 int startlineNum = 1;//写入文件的行数
12 int Multiplying = 2;//行数增长倍率
13
14 long begin = 0L;
15 long end = 0L;
16
17 //将时间统计写入文件Result.txt中
18 FileWriter fileWriter = new FileWriter("./Result.txt", true);
19 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
20
21 System.out.println("Test FileOutputStream begin.");
22 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
23 begin = System.currentTimeMillis();
24 testFileOutputStream(lineNum);
25 end = System.currentTimeMillis();
26 long timeElapse_FileOutputStream = end - begin;
27 bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"\t");
28 }
29 System.out.println("Test FileOutputStream end.\n");
30
31 System.out.println("Test BufferedOutputStream begin.");
32 bufferedWriter.write("\n");
33 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
34 begin = System.currentTimeMillis();
35 testBufferedOutputStream(lineNum);
36 end = System.currentTimeMillis();
37 long timeElapse_BufferedOutputStream = end - begin;
38 bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"\t");
39 }
40 System.out.println("Test BufferedOutputStream end.\n");
41
42 System.out.println("Test FileWriter begin.");
43 bufferedWriter.write("\n");
44 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
45 begin = System.currentTimeMillis();
46 testFileWriter(lineNum);
47 end = System.currentTimeMillis();
48 long timeElapse_FileWriter = end - begin;
49 bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"\t");
50 }
51 System.out.println("Test FileWriter end.\n");
52
53 System.out.println("Test BufferedWriter begin.");
54 bufferedWriter.write("\n");
55 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
56 begin = System.currentTimeMillis();
57 testBufferedWriter(lineNum);
58 end = System.currentTimeMillis();
59 long timeElapse_BufferedWriter = end - begin;
60 bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"\t");
61 }
62 System.out.println("Test BufferedWriter end.\n");
63
64 System.out.println("Test NewOutputStream begin.");
65 bufferedWriter.write("\n");
66 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
67 begin = System.currentTimeMillis();
68 testNewOutputStream(lineNum);
69 end = System.currentTimeMillis();
70 long timeElapse_NewOutputStream = end - begin;
71 bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"\t");
72 }
73 System.out.println("Test NewOutputStream end.\n");
74
75 System.out.println("Test NewBufferedWriter begin.");
76 bufferedWriter.write("\n");
77 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
78 begin = System.currentTimeMillis();
79 testNewBufferedWriter(lineNum);
80 end = System.currentTimeMillis();
81 long timeElapse_NewBufferedWriter = end - begin;
82 bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"\t");
83 }
84 System.out.println("Test NewOutputStream end.\n");
85
86 bufferedWriter.close();
87 }
88
89 /************************** I/O *****************************/
90 //面向字节
91 public static void testFileOutputStream (int lineNum) throws IOException {
92 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
93 while (--lineNum > 0) {
94 fileOutputStream.write("写入文件Data\n".getBytes());
95 }
96 fileOutputStream.close();
97 }
98
99 public static void testBufferedOutputStream (int lineNum) throws IOException {
100 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
101 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
102 while (--lineNum > 0) {
103 bufferedOutputStream.write("写入文件Data\n".getBytes());
104 }
105 bufferedOutputStream.close();
106 }
107
108 //面向字符
109 public static void testFileWriter (int lineNum) throws IOException {
110 FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
111 while (--lineNum > 0) {
112 fileWriter.write("写入文件Data\n");
113 }
114 fileWriter.close();
115 }
116
117 public static void testBufferedWriter (int lineNum) throws IOException {
118 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
119 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
120 while (--lineNum > 0) {
121 bufferedWriter.write("写入文件Data\n");
122 }
123 bufferedWriter.close();
124 }
125
126
127 /************************** NIO ****************************/
128 public static void testNewOutputStream (int lineNum) throws IOException {
129 OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
130 while (--lineNum > 0) {
131 outputStream.write("写入文件Data\n".getBytes());
132 }
133 outputStream.close();
134 }
135
136 public static void testNewBufferedWriter (int lineNum) throws IOException {
137 BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
138 while (--lineNum > 0) {
139 newBufferedReader.write("写入文件Data\n");
140 }
141 newBufferedReader.close();
142 }
143
144
145 public static void main (String[] args) throws IOException {
146 //多次测试时可清空result.txt文件
147 FileWriter fileWriter = new FileWriter("./Result.txt");
148 testDriver();
149 }
150 }
测试结果

从上图可以看出,写入行数超过20W以上时,FileOutputStream和NewOutputStream耗费时间远远超出其他4个类。为了清晰,让我们放大其他4个类的图:
可以看出,这4个类中,BufferWriter和NewBufferedWriter所耗费时间更少,但总体差别不是很大。
让我们再来看看,写入26W行数据以下时的情况:
可以看出,在数据量较小的情况下,这4个类所耗费时间的差异并不是很大,在更小的数据量下,它们的效率几乎没有差别。
后记
从以上分析可知(注意横坐标写入行数是指数级增加的),各个类的时间复杂度大致为O(k),其中不同的类的k不同,导致了最终巨大的差异。
这里只给出了测试结果,并未很深入地分析其底层实现原理,欢迎评论区留言。
另外,我没有在其他机器测试,有兴趣的小伙伴可以将自己的测试结果发出来,共同进步^_^
附件
本次测试数据结果(若看不清,可以将浏览器字体放大,或下载到本地看)
~~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~
评论区小伙伴“ andorxor”提出:
XXXOutputStream是用来写二进制的,你把字符串转换成字节数组再写自然就慢了,主要慢在转换的过程。
因此,将程序修改,提前把字符和字节内容都准备好,再次验证。新程序如下:
1 import java.io.File;
2 import java.io.FileOutputStream;
3 import java.io.*;
4 import java.nio.file.Files;
5 import java.nio.file.Paths;
6
7 public class testFileIO {
8
9
10 public static void testDriver () throws IOException {
11 int maxlineNum = 100000001;//写入文件的最大行数
12 int startlineNum = 1;//写入文件的行数
13 int Multiplying = 2;//行数增长倍率
14
15 String contentChars = "写入文件Data\n";//每行的内容(字符流)
16 byte[] contentBytes = "写入文件Data\n".getBytes();//每行的内容(字节流)
17
18 long begin = 0L;
19 long end = 0L;
20
21 //将时间统计写入文件Result.txt中
22 FileWriter fileWriter = new FileWriter("./Result.txt", true);
23 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
24
25 System.out.println("Test FileOutputStream begin.");
26 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
27 begin = System.currentTimeMillis();
28 testFileOutputStream(lineNum,contentBytes);
29 end = System.currentTimeMillis();
30 long timeElapse_FileOutputStream = end - begin;
31 bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"\t");
32 }
33 System.out.println("Test FileOutputStream end.\n");
34
35 System.out.println("Test BufferedOutputStream begin.");
36 bufferedWriter.write("\n");
37 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
38 begin = System.currentTimeMillis();
39 testBufferedOutputStream(lineNum,contentBytes);
40 end = System.currentTimeMillis();
41 long timeElapse_BufferedOutputStream = end - begin;
42 bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"\t");
43 }
44 System.out.println("Test BufferedOutputStream end.\n");
45
46 System.out.println("Test FileWriter begin.");
47 bufferedWriter.write("\n");
48 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
49 begin = System.currentTimeMillis();
50 testFileWriter(lineNum,contentChars);
51 end = System.currentTimeMillis();
52 long timeElapse_FileWriter = end - begin;
53 bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"\t");
54 }
55 System.out.println("Test FileWriter end.\n");
56
57 System.out.println("Test BufferedWriter begin.");
58 bufferedWriter.write("\n");
59 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
60 begin = System.currentTimeMillis();
61 testBufferedWriter(lineNum,contentChars);
62 end = System.currentTimeMillis();
63 long timeElapse_BufferedWriter = end - begin;
64 bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"\t");
65 }
66 System.out.println("Test BufferedWriter end.\n");
67
68 System.out.println("Test NewOutputStream begin.");
69 bufferedWriter.write("\n");
70 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
71 begin = System.currentTimeMillis();
72 testNewOutputStream(lineNum,contentBytes);
73 end = System.currentTimeMillis();
74 long timeElapse_NewOutputStream = end - begin;
75 bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"\t");
76 }
77 System.out.println("Test NewOutputStream end.\n");
78
79 System.out.println("Test NewBufferedWriter begin.");
80 bufferedWriter.write("\n");
81 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
82 begin = System.currentTimeMillis();
83 testNewBufferedWriter(lineNum,contentChars);
84 end = System.currentTimeMillis();
85 long timeElapse_NewBufferedWriter = end - begin;
86 bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"\t");
87 }
88 System.out.println("Test NewOutputStream end.\n");
89
90 bufferedWriter.close();
91 }
92
93 /************************** I/O *****************************/
94 //面向字节
95 public static void testFileOutputStream (int lineNum, byte[] content) throws IOException {
96 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
97 while (--lineNum > 0) {
98 fileOutputStream.write(content);
99 }
100 fileOutputStream.close();
101 }
102
103 public static void testBufferedOutputStream (int lineNum, byte[] content) throws IOException {
104 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
105 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
106 while (--lineNum > 0) {
107 bufferedOutputStream.write(content);
108 }
109 bufferedOutputStream.close();
110 }
111
112 //面向字符
113 public static void testFileWriter (int lineNum, String content) throws IOException {
114 FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
115 while (--lineNum > 0) {
116 fileWriter.write(content);
117 }
118 fileWriter.close();
119 }
120
121 public static void testBufferedWriter (int lineNum, String content) throws IOException {
122 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
123 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
124 while (--lineNum > 0) {
125 bufferedWriter.write(content);
126 }
127 bufferedWriter.close();
128 }
129
130
131 /************************** NIO ****************************/
132 public static void testNewOutputStream (int lineNum, byte[] content) throws IOException {
133 OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
134 while (--lineNum > 0) {
135 outputStream.write(content);
136 }
137 outputStream.close();
138 }
139
140 public static void testNewBufferedWriter (int lineNum,String content) throws IOException {
141 BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
142 while (--lineNum > 0) {
143 newBufferedReader.write(content);
144 }
145 newBufferedReader.close();
146 }
147
148
149 public static void main (String[] args) throws IOException {
150 //多次测试时可清空result.txt文件
151 FileWriter fileWriter = new FileWriter("./Result.txt");
152 testDriver();
153 }
154 }
View Code
结果为:
可以看出和前面的案例几乎没有差异(图就不画了)。
所以XXXOutputStream效率低的原因并不是字符串转换成字节数组,而是其本身的实现方式所致。
~~~~~~~~~~~~~~~~~~~~~分割线:底层实现原理浅谈~~~~~~~~~~~~~~~~~~~~~~~
其实,计算机中都是针对字节操作的(即字符都要经过编码转换为字节),那么问题来了,FileOutputStream为什么比FileWriter(FileWriter内部还有FileOutputStream转换操作,具体看源码)还要慢呢?且慢,让我们把写入文件的数据改一下:
1 import java.io.File;
2 import java.io.FileOutputStream;
3 import java.io.*;
4 import java.nio.file.Files;
5 import java.nio.file.Paths;
6
7 public class testFileIO {
8
9
10 public static void testDriver () throws IOException {
11 int maxlineNum = 500001;//写入文件的最大行数
12 int startlineNum = 1;//写入文件的行数
13 int Multiplying = 2;//行数增长倍率
14
15 String baseContent = "背景\n" +
16 "考虑以下场景:\n" +
17 "\n" +
18 "InfoTable(信息表):\n" +
19 "\n" +
20 "Name\tGender\tAge\tScore\n" +
21 "张三\t男\t21\t90\n" +
22 "李四\t女\t20\t87\n" +
23 "王五\t男\t22\t92\n" +
24 "赵六\t女\t19\t94\n" +
25 "孙七\t女\t23\t88\n" +
26 "周八\t男\t20\t91\n" +
27 "StatusTable(状态表,指是否有在考试之前复习):\n" +
28 "\n" +
29 "Name\thasReview\n" +
30 "张三\t是\n" +
31 "李四\t否\n" +
32 "王五\t是\n" +
33 "赵六\t是\n" +
34 "孙七\t否\n" +
35 "周八\t是\n" +
36 "现在,我想知道所有复习过的学生的成绩,可以利用mysql中的子查询来实现:\n" +
37 "\n" +
38 "SELECT Score \n" +
39 "FROM InfoTable \n" +
40 "WHERE Name in (SELECT Name \n" +
41 " FROM StatusTable \n" +
42 " WHERE hasReview = '是');\n" +
43 "这种方式非常方便,我们只要把查询条件写出来,剩下的操作都由mysql来处理。而在实际场景中,为了减少底层耦合,我们一般不通过mysql中的子查询方式联表查询,而是先执行子查询得到结果集,再以结果集作为条件执行外层查询。通常情况下,子查询和外层查询由上层的不同服务执行,这样就在一定程度上达到了底层数据库解耦的目的。注意这种实现方式将mysql内部的一部分复杂操作抛给了我们。这时,Mybatis中的foreach标签就有了用武之地。\n" +
44 "\n" +
45 "Mybatis 中foreach标签的用法\n" +
46 "还以刚才的例子来说,先执行子查询\n" +
47 "\n" +
48 "SELECT Name FROM StatusTable WHERE hasReview = '是'\n" +
49 "再执行外层查询,就是\n" +
50 "\n" +
51 "SELECT Score \n" +
52 "FROM InfoTable \n" +
53 "WHERE Name in ('张三' , '王五', '赵六', '周八');\n" +
54 "也就是一个批量查询操作,将其抽象一下(假设有三个条件):\n" +
55 "\n" +
56 "SELECT * \n" +
57 "FROM <tableName> \n" +
58 "WHERE <ColumnName> IN (<case1>,<case2>,<case3>)\n" +
59 "实际情况中,case可能远不止3个,这时可以在XXXMapper.xml文件中利用Mybatis中的foreach编写sql语句:\n" +
60 "\n" +
61 "SELECT * \n" +
62 "FROM <tableName> \n" +
63 "WHERE <ColumnName> IN \n" +
64 "<foreach collection=\"list\" index=\"index\" item=\"item\" open=\"(\" separator=\",\" close=\")\">\n" +
65 " #{item}\n" +
66 "</foreach>\n" +
67 "就可以实现相同的效果了。\n" +
68 "\n" +
69 "那么问题来了,foreach标签中各种参数是什么含义呢?\n" +
70 "\n" +
71 "collection\n" +
72 "如果传入的是单参数且参数类型是一个List的时候,collection属性值为list\n" +
73 "如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array\n" +
74 "如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key\n" +
75 "index 集合迭代位置\n" +
76 "item 集合中的每一个元素别名\n" +
77 "open 开始符号,例如这里的(,就对应于IN (<case1>,<case2>,<case3>)中IN后面的第一个(\n" +
78 "separator 分隔符,例如这里的,,就对应于IN (<case1>,<case2>,<case3>)中的,\n" +
79 "close 结束符号,例如这里的),就对应于IN (<case1>,<case2>,<case3>)中<case3>后面的)\n" +
80 "参考\n";
81
82 String contentChars = baseContent;//每行的内容(字符流)
83 byte[] contentBytes = baseContent.getBytes();//每行的内容(字节流)
84
85 long begin = 0L;
86 long end = 0L;
87
88 //将时间统计写入文件Result.txt中
89 FileWriter fileWriter = new FileWriter("./Result.txt", true);
90 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
91
92 System.out.println("Test FileOutputStream begin.");
93 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
94 begin = System.currentTimeMillis();
95 testFileOutputStream(lineNum,contentBytes);
96 end = System.currentTimeMillis();
97 long timeElapse_FileOutputStream = end - begin;
98 bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"\t");
99 }
100 System.out.println("Test FileOutputStream end.\n");
101
102 System.out.println("Test BufferedOutputStream begin.");
103 bufferedWriter.write("\n");
104 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
105 begin = System.currentTimeMillis();
106 testBufferedOutputStream(lineNum,contentBytes);
107 end = System.currentTimeMillis();
108 long timeElapse_BufferedOutputStream = end - begin;
109 bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"\t");
110 }
111 System.out.println("Test BufferedOutputStream end.\n");
112
113 System.out.println("Test FileWriter begin.");
114 bufferedWriter.write("\n");
115 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
116 begin = System.currentTimeMillis();
117 testFileWriter(lineNum,contentChars);
118 end = System.currentTimeMillis();
119 long timeElapse_FileWriter = end - begin;
120 bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"\t");
121 }
122 System.out.println("Test FileWriter end.\n");
123
124 System.out.println("Test BufferedWriter begin.");
125 bufferedWriter.write("\n");
126 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
127 begin = System.currentTimeMillis();
128 testBufferedWriter(lineNum,contentChars);
129 end = System.currentTimeMillis();
130 long timeElapse_BufferedWriter = end - begin;
131 bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"\t");
132 }
133 System.out.println("Test BufferedWriter end.\n");
134
135 System.out.println("Test NewOutputStream begin.");
136 bufferedWriter.write("\n");
137 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
138 begin = System.currentTimeMillis();
139 testNewOutputStream(lineNum,contentBytes);
140 end = System.currentTimeMillis();
141 long timeElapse_NewOutputStream = end - begin;
142 bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"\t");
143 }
144 System.out.println("Test NewOutputStream end.\n");
145
146 System.out.println("Test NewBufferedWriter begin.");
147 bufferedWriter.write("\n");
148 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
149 begin = System.currentTimeMillis();
150 testNewBufferedWriter(lineNum,contentChars);
151 end = System.currentTimeMillis();
152 long timeElapse_NewBufferedWriter = end - begin;
153 bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"\t");
154 }
155 System.out.println("Test NewOutputStream end.\n");
156
157 bufferedWriter.close();
158 }
159
160 /************************** I/O *****************************/
161 //面向字节
162 public static void testFileOutputStream (int lineNum, byte[] content) throws IOException {
163 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
164 while (--lineNum > 0) {
165 fileOutputStream.write(content);
166 }
167 fileOutputStream.close();
168 }
169
170 public static void testBufferedOutputStream (int lineNum, byte[] content) throws IOException {
171 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
172 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
173 while (--lineNum > 0) {
174 bufferedOutputStream.write(content);
175 }
176 bufferedOutputStream.close();
177 }
178
179 //面向字符
180 public static void testFileWriter (int lineNum, String content) throws IOException {
181 FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
182 while (--lineNum > 0) {
183 fileWriter.write(content);
184 }
185 fileWriter.close();
186 }
187
188 public static void testBufferedWriter (int lineNum, String content) throws IOException {
189 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
190 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
191 while (--lineNum > 0) {
192 bufferedWriter.write(content);
193 }
194 bufferedWriter.close();
195 }
196
197
198 /************************** NIO ****************************/
199 public static void testNewOutputStream (int lineNum, byte[] content) throws IOException {
200 OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
201 while (--lineNum > 0) {
202 outputStream.write(content);
203 }
204 outputStream.close();
205 }
206
207 public static void testNewBufferedWriter (int lineNum,String content) throws IOException {
208 BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
209 while (--lineNum > 0) {
210 newBufferedReader.write(content);
211 }
212 newBufferedReader.close();
213 }
214
215
216 public static void main (String[] args) throws IOException {
217 //多次测试时可清空result.txt文件
218 FileWriter fileWriter = new FileWriter("./Result.txt");
219 testDriver();
220 }
221 }
这次数据量就很大了,结果也就变了:
所以,数据量很小的情况下,字符到字节的编码操作带来的性能降低几乎忽略不计;而数据量很大的时候,编码耗费的时间就很可观了。至于为什么在小数据量的情况下FileWriter快很多,目前我认为是一次操作两个字节所致(有了缓存之后就差不多了)。
参考
Java IO流学习总结
『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』