前言
众所周知,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 importjava.io.File;2 importjava.io.FileOutputStream;3 import java.io.*;4 importjava.nio.file.Files;5 importjava.nio.file.Paths;6
7 public classtestFileIO {8
9 public static void testDriver () throwsIOException {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 = newBufferedWriter(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) throwsIOException {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) throwsIOException {100 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));101 BufferedOutputStream bufferedOutputStream = newBufferedOutputStream(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) throwsIOException {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) throwsIOException {118 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");119 BufferedWriter bufferedWriter = newBufferedWriter(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) throwsIOException {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) throwsIOException {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) throwsIOException {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 importjava.io.File;2 importjava.io.FileOutputStream;3 import java.io.*;4 importjava.nio.file.Files;5 importjava.nio.file.Paths;6
7 public classtestFileIO {8
9
10 public static void testDriver () throwsIOException {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 = newBufferedWriter(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) throwsIOException {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) throwsIOException {104 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));105 BufferedOutputStream bufferedOutputStream = newBufferedOutputStream(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) throwsIOException {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) throwsIOException {122 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");123 BufferedWriter bufferedWriter = newBufferedWriter(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) throwsIOException {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) throwsIOException {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) throwsIOException {150 //多次测试时可清空result.txt文件
151 FileWriter fileWriter = new FileWriter("./Result.txt");152 testDriver();153 }154 }
View Code
结果为:
可以看出和前面的案例几乎没有差异(图就不画了)。
所以XXXOutputStream效率低的原因并不是字符串转换成字节数组,而是其本身的实现方式所致。
~~~~~~~~~~~~~~~~~~~~~分割线:底层实现原理浅谈~~~~~~~~~~~~~~~~~~~~~~~
其实,计算机中都是针对字节操作的(即字符都要经过编码转换为字节),那么问题来了,FileOutputStream为什么比FileWriter(FileWriter内部还有FileOutputStream转换操作,具体看源码)还要慢呢?且慢,让我们把写入文件的数据改一下:
1 importjava.io.File;2 importjava.io.FileOutputStream;3 import java.io.*;4 importjava.nio.file.Files;5 importjava.nio.file.Paths;6
7 public classtestFileIO {8
9
10 public static void testDriver () throwsIOException {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 \n" +
58 "WHERE IN (,,)\n" +
59 "实际情况中,case可能远不止3个,这时可以在XXXMapper.xml文件中利用Mybatis中的foreach编写sql语句:\n" +
60 "\n" +
61 "SELECT * \n" +
62 "FROM \n" +
63 "WHERE IN \n" +
64 "\n" +
65 " #{item}\n" +
66 "\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 (,,)中IN后面的第一个(\n" +
78 "separator 分隔符,例如这里的,,就对应于IN (,,)中的,\n" +
79 "close 结束符号,例如这里的),就对应于IN (,,)中后面的)\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 = newBufferedWriter(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) throwsIOException {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) throwsIOException {171 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));172 BufferedOutputStream bufferedOutputStream = newBufferedOutputStream(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) throwsIOException {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) throwsIOException {189 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");190 BufferedWriter bufferedWriter = newBufferedWriter(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) throwsIOException {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) throwsIOException {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) throwsIOException {217 //多次测试时可清空result.txt文件
218 FileWriter fileWriter = new FileWriter("./Result.txt");219 testDriver();220 }221 }
View Code
这次数据量就很大了,结果也就变了:
所以,数据量很小的情况下,字符到字节的编码操作带来的性能降低几乎忽略不计;而数据量很大的时候,编码耗费的时间就很可观了。至于为什么在小数据量的情况下FileWriter快很多,目前我认为是一次操作两个字节所致(有了缓存之后就差不多了)。
参考