干Java這么久,一直在做WEB相關的項目,一些基礎類差不多都已經忘記。經常想得撿起,但總是因為一些原因,不能如愿。
其實不是沒有時間,只是有些時候疲于總結,今得空,下定決心將丟掉的都給撿起來。
文件讀寫是一個在項目中經常遇到的工作,有些時候是因為維護,有些時候是新功能開發。我們的任務總是很重,工作節奏很快,快到我們不能停下腳步去總結。
文件讀寫有以下幾種常用的方法
1、字節讀寫(InputStream/OutputStream)
2、字符讀取(FileReader/FileWriter)
3、行讀取(BufferedReader/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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; /** * <b>文件讀取類</b><br /> * 1、按字節讀取文件內容<br /> * 2、按字符讀取文件內容<br /> * 3、按行讀取文件內容<br /> * @author qin_xijuan * */ public class FileOperate { private static final String FILE_PATH = "d:/work/the List of Beautiful Music.txt" ; /** * 以字節為單位讀取文件內容 * @param filePath:需要讀取的文件路徑 */ public static void readFileBybyte(String filePath) { File file = new File(filePath); // InputStream:此抽象類是表示字節輸入流的所有類的超類。 InputStream ins = null ; try { // FileInputStream:從文件系統中的某個文件中獲得輸入字節。 ins = new FileInputStream(file); int temp ; // read():從輸入流中讀取數據的下一個字節。 while ((temp = ins.read())!=- 1 ){ System.out.write(temp); } } catch (Exception e){ e.getStackTrace(); } finally { if (ins != null ){ try { ins.close(); } catch (IOException e){ e.getStackTrace(); } } } } /** * 以字符為單位讀取文件內容 * @param filePath */ public static void readFileByCharacter(String filePath){ File file = new File(filePath); // FileReader:用來讀取字符文件的便捷類。 FileReader reader = null ; try { reader = new FileReader(file); int temp ; while ((temp = reader.read()) != - 1 ){ if ((( char ) temp) != '\r' ) { System.out.print(( char ) temp); } } } catch (IOException e){ e.getStackTrace(); } finally { if (reader != null ){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 以行為單位讀取文件內容 * @param filePath */ public static void readFileByLine(String filePath){ File file = new File(filePath); // BufferedReader:從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。 BufferedReader buf = null ; try { // FileReader:用來讀取字符文件的便捷類。 buf = new BufferedReader( new FileReader(file)); // buf = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String temp = null ; while ((temp = buf.readLine()) != null ){ System.out.println(temp); } } catch (Exception e){ e.getStackTrace(); } finally { if (buf != null ){ try { buf.close(); } catch (IOException e) { e.getStackTrace(); } } } } public static void main(String args[]) { readFileBybyte(FILE_PATH); readFileByCharacter(FILE_PATH); readFileByLine(FILE_PATH); } } |
//-----------------------------------------------------------------分割線-----------------------------------------------------------------------------
再經過兩位同行的提點下,我對之前寫的文件做了點修改,并通過讀寫一個1.2M的文本文件來測試各方法的性能。從多次測試結果來看,行讀寫卻是是Java.nio更有效率。
經過修改之后的代碼如下:
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
package com.waddell.basic; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * <b>文件讀取類</b><br /> * 1、按字節讀取文件內容<br /> * 2、按字符讀取文件內容<br /> * 3、按行讀取文件內容<br /> * * @author qin_xijuan * */ public class FileOperate { private static final String FILE_PATH = "d:/work/jipinwodi.txt" ; /** * 以字節為單位讀寫文件內容 * * @param filePath * :需要讀取的文件路徑 */ public static void readFileBybyte(String filePath) { File file = new File(filePath); // InputStream:此抽象類是表示字節輸入流的所有類的超類。 InputStream ins = null ; OutputStream outs = null ; try { // FileInputStream:從文件系統中的某個文件中獲得輸入字節。 ins = new FileInputStream(file); outs = new FileOutputStream( "d:/work/readFileByByte.txt" ); int temp; // read():從輸入流中讀取數據的下一個字節。 while ((temp = ins.read()) != - 1 ) { outs.write(temp); } } catch (Exception e) { e.getStackTrace(); } finally { if (ins != null && outs != null ) { try { outs.close(); ins.close(); } catch (IOException e) { e.getStackTrace(); } } } } /** * 以字符為單位讀寫文件內容 * * @param filePath */ public static void readFileByCharacter(String filePath) { File file = new File(filePath); // FileReader:用來讀取字符文件的便捷類。 FileReader reader = null ; FileWriter writer = null ; try { reader = new FileReader(file); writer = new FileWriter( "d:/work/readFileByCharacter.txt" ); int temp; while ((temp = reader.read()) != - 1 ) { writer.write(( char )temp); } } catch (IOException e) { e.getStackTrace(); } finally { if (reader != null && writer != null ) { try { reader.close(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 以行為單位讀寫文件內容 * * @param filePath */ public static void readFileByLine(String filePath) { File file = new File(filePath); // BufferedReader:從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。 BufferedReader bufReader = null ; BufferedWriter bufWriter = null ; try { // FileReader:用來讀取字符文件的便捷類。 bufReader = new BufferedReader( new FileReader(file)); bufWriter = new BufferedWriter( new FileWriter( "d:/work/readFileByLine.txt" )); // buf = new BufferedReader(new InputStreamReader(new // FileInputStream(file))); String temp = null ; while ((temp = bufReader.readLine()) != null ) { bufWriter.write(temp+ "\n" ); } } catch (Exception e) { e.getStackTrace(); } finally { if (bufReader != null && bufWriter != null ) { try { bufReader.close(); bufWriter.close(); } catch (IOException e) { e.getStackTrace(); } } } } /** * 使用Java.nio ByteBuffer字節將一個文件輸出至另一文件 * * @param filePath */ public static void readFileByBybeBuffer(String filePath) { FileInputStream in = null ; FileOutputStream out = null ; try { // 獲取源文件和目標文件的輸入輸出流 in = new FileInputStream(filePath); out = new FileOutputStream( "d:/work/readFileByBybeBuffer.txt" ); // 獲取輸入輸出通道 FileChannel fcIn = in.getChannel(); FileChannel fcOut = out.getChannel(); ByteBuffer buffer = ByteBuffer.allocate( 1024 ); while ( true ) { // clear方法重設緩沖區,使它可以接受讀入的數據 buffer.clear(); // 從輸入通道中將數據讀到緩沖區 int r = fcIn.read(buffer); if (r == - 1 ) { break ; } // flip方法讓緩沖區可以將新讀入的數據寫入另一個通道 buffer.flip(); fcOut.write(buffer); } } catch (Exception e) { e.printStackTrace(); } finally { if (in != null && out != null ) { try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static long getTime(){ return System.currentTimeMillis(); } public static void main(String args[]) { long time1 = getTime() ; // readFileByByte(FILE_PATH);// 8734,8281,8000,7781,8047 // readFileByCharacter(FILE_PATH);// 734, 437, 437, 438, 422 // readFileByLine(FILE_PATH);// 110, 94, 94, 110, 93 readFileByBybeBuffer(FILE_PATH); // 125, 78, 62, 78, 62 long time2 = getTime() ; System.out.println(time2-time1); } } |
在main方法中,調用各方法之后,有五組數據,分辨是我5次讀寫文件測試出來的時間(毫秒)。
關于Java.nio請參考:http://m.ythuaji.com.cn/article/146072.html
個人測試:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public static void main(String args[]) { long time1 = getTime() ; // readFileByByte(FILE_PATH); //2338,2286 // readFileByCharacter(FILE_PATH);//160,162,158 // readFileByLine(FILE_PATH); //46,51,57 // readFileByBybeBuffer(FILE_PATH);//19,18,17 // readFileByBybeBuffer(FILE_PATH);//2048: 11,13 // readFileByBybeBuffer(FILE_PATH);//1024*100 100k,711k: 6,6 // readFileByBybeBuffer(FILE_PATH);//1024*100 100k,1422k: 7 // readFileByBybeBuffer(FILE_PATH);//1024*100 100k,9951k: 49,48 // readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,711k: 7,7 // readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,1422k: 7,8 // readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,9951k: 48,49 // readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,711k: 21,13,17 // readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,1422k: 16,17,14,15 // readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,9951k:64,60 long time2 = getTime() ; System.out.println(time2-time1); } |
總結
以上就是本文關于Java文件讀寫IO/NIO及性能比較詳細代碼及總結的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
原文鏈接:http://blog.csdn.net/chenleixing/article/details/44207469