在软件系统中,IO速度比内存速度慢,IO读写在很多情况下会是系统的瓶颈。
在java标准IO操作中,InputStream和OutputStream提供基于流的IO操作,以字节为处理单位;Reader和Writer实现了Buffered缓存,以字符为处理单位。
从Java1.4开始,增加NIO(New IO),增加缓存Buffer和通道Channel,以块为处理单位,是双向通道(可读可写,类似RandomAccessFile),支持锁和内存映射文件访问接口,大大提升了IO速度。
以下例子简单测试常见IO操作的性能速度。
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
/**
* 测试不同io操作速度
*
* @author peter_wang
* @create-time 2014-6-4 下午12:52:48
*/
public
class
SpeedTest {
private
static
final
String INPUT_FILE_PATH =
"io_speed.txt"
;
private
static
final
String OUTPUT_FILE_PATH =
"io_speed_copy.txt"
;
/**
* @param args
*/
public
static
void
main(String[] args) {
long
ioStreamTime1 = ioStreamCopy();
System.out.println(
"io stream copy:"
+ ioStreamTime1);
long
ioStreamTime2 = bufferedStreamCopy();
System.out.println(
"buffered stream copy:"
+ ioStreamTime2);
long
ioStreamTime3 = nioStreamCopy();
System.out.println(
"nio stream copy:"
+ ioStreamTime3);
long
ioStreamTime4 = nioMemoryStreamCopy();
System.out.println(
"nio memory stream copy:"
+ ioStreamTime4);
}
/**
* 普通文件流读写
*
* @return 操作的时间
*/
private
static
long
ioStreamCopy() {
long
costTime = -
1
;
FileInputStream is =
null
;
FileOutputStream os =
null
;
try
{
long
startTime = System.currentTimeMillis();
is =
new
FileInputStream(INPUT_FILE_PATH);
os =
new
FileOutputStream(OUTPUT_FILE_PATH);
int
read = is.read();
while
(read != -
1
) {
os.write(read);
read = is.read();
}
long
endTime = System.currentTimeMillis();
costTime = endTime - startTime;
}
catch
(FileNotFoundException e) {
e.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
finally
{
try
{
if
(is !=
null
) {
is.close();
}
if
(os !=
null
) {
os.close();
}
}
catch
(IOException e) {
e.printStackTrace();
}
}
return
costTime;
}
/**
* 加入缓存的文件流读写, Reader默认实现缓存,只能读取字符文件,无法准确读取字节文件如图片视频等
*
* @return 操作的时间
*/
private
static
long
bufferedStreamCopy() {
long
costTime = -
1
;
FileReader reader =
null
;
FileWriter writer =
null
;
try
{
long
startTime = System.currentTimeMillis();
reader =
new
FileReader(INPUT_FILE_PATH);
writer =
new
FileWriter(OUTPUT_FILE_PATH);
int
read = -
1
;
while
((read = reader.read()) != -
1
) {
writer.write(read);
}
writer.flush();
long
endTime = System.currentTimeMillis();
costTime = endTime - startTime;
}
catch
(FileNotFoundException e) {
e.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
finally
{
try
{
if
(reader !=
null
) {
reader.close();
}
if
(writer !=
null
) {
writer.close();
}
}
catch
(IOException e) {
e.printStackTrace();
}
}
return
costTime;
}
/**
* nio操作数据流
*
* @return 操作的时间
*/
private
static
long
nioStreamCopy() {
long
costTime = -
1
;
FileInputStream is =
null
;
FileOutputStream os =
null
;
FileChannel fi =
null
;
FileChannel fo =
null
;
try
{
long
startTime = System.currentTimeMillis();
is =
new
FileInputStream(INPUT_FILE_PATH);
os =
new
FileOutputStream(OUTPUT_FILE_PATH);
fi = is.getChannel();
fo = os.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(
1024
);
while
(
true
) {
buffer.clear();
int
read = fi.read(buffer);
if
(read == -
1
) {
break
;
}
buffer.flip();
fo.write(buffer);
}
long
endTime = System.currentTimeMillis();
costTime = endTime - startTime;
}
catch
(FileNotFoundException e) {
e.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
finally
{
try
{
if
(fi !=
null
) {
fi.close();
}
if
(fo !=
null
) {
fo.close();
}
if
(is !=
null
) {
is.close();
}
if
(os !=
null
) {
os.close();
}
}
catch
(IOException e) {
e.printStackTrace();
}
}
return
costTime;
}
/**
* nio内存映射操作数据流
*
* @return 操作的时间
*/
private
static
long
nioMemoryStreamCopy() {
long
costTime = -
1
;
FileInputStream is =
null
;
//映射文件输出必须用RandomAccessFile
RandomAccessFile os =
null
;
FileChannel fi =
null
;
FileChannel fo =
null
;
try
{
long
startTime = System.currentTimeMillis();
is =
new
FileInputStream(INPUT_FILE_PATH);
os =
new
RandomAccessFile(OUTPUT_FILE_PATH,
"rw"
);
fi = is.getChannel();
fo = os.getChannel();
IntBuffer iIb=fi.map(FileChannel.MapMode.READ_ONLY,
0
, fi.size()).asIntBuffer();
IntBuffer oIb = fo.map(FileChannel.MapMode.READ_WRITE,
0
, fo.size()).asIntBuffer();
while
(iIb.hasRemaining()){
int
read = iIb.get();
oIb.put(read);
}
long
endTime = System.currentTimeMillis();
costTime = endTime - startTime;
}
catch
(FileNotFoundException e) {
e.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
finally
{
try
{
if
(fi !=
null
) {
fi.close();
}
if
(fo !=
null
) {
fo.close();
}
if
(is !=
null
) {
is.close();
}
if
(os !=
null
) {
os.close();
}
}
catch
(IOException e) {
e.printStackTrace();
}
}
return
costTime;
}
}
|
1
2
3
4
|
io stream copy:
384
buffered stream copy:
125
nio stream copy:
12
nio memory stream copy:
10
|