java-IO操作性能对比

在软件系统中,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
结论分析: 最普通的InputStream操作耗时较长,增加了缓存后速度增加了,用了nio和内存映射访问文件,速度最快。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值