前言
衆所周知,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/』