测试复制文件的大小:4.5MB
1 /*
2
3 * BufferedInputStram&BufferedOutputStream
4
5 * 这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入
6
7 * 或读取操作时,都会加上缓冲,这种流模式提高了IO的性能
8
9 *
10
11 * 从应用程序中把输入放入文件,相当于将一缸水倒入到另一个
12
13 * 缸中:
14
15 * FileOutPutStream----->write()方法相当于一滴一滴的
16
17 * 把水转移过去
18
19 * DataOutputStream----->writeXxx()方法会方便一些,相当于
20
21 * 一瓢一瓢的把水转移过去
22
23 * BufferedOutputStream---write方法更方便,相当于把水一瓢
24
25 * 一瓢先放入桶中,在从桶中倒入得到缸中
26
27 * */
28
29
30
31
32
33 package Zhang;
34
35
36
37 import java.io.BufferedInputStream;
38
39 import java.io.BufferedOutputStream;
40
41 import java.io.File;
42
43 import java.io.FileInputStream;
44
45 import java.io.FileOutputStream;
46
47 import java.io.IOException;
48
49
50
51
52
53 public class IOUtil {
54
55 /**
56
57 * 读取指定的文件内容,按照十六进制输出到控制台
58
59 * 并且每输出10个byte换行
60
61 * @param fileName 文件名
62
63 * @throws FileNotFoundException
64
65 * */
66
67 public static void printHex(String fileName) throws Exception{
68
69 FileInputStream in=new FileInputStream(fileName);
70
71 int b;
72
73 int i=1;//每十个字节换行。
74
75 while((b=in.read())!=-1){
76
77 if(b<=0xf){
78
79 //单位十六进制数,前面补0
80
81 System.out.print("0");
82
83 }
84
85 System.out.print(Integer.toHexString(b)+" ");
86
87 if(i++%10==0){//够十个换行
88
89 System.out.println();
90
91 }
92
93 }
94
95 in.close();
96
97 }
98
99 public static void printHexByByteArray(String fileName)throws Exception{
100
101 FileInputStream in=new FileInputStream(fileName);
102
103 byte[] buf=new byte[10*1024]; //20KB
104
105
106
107 /*
108
109 * 从in中批量读取字节,放入到buf这个字节数组中,从0开始放,
110
111 * 最多放buf.length个,返回的是读取到的字节的个数
112
113 * */
114
115 /*
116
117 int bytes=in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
118
119 //bytes是实际读取到的长度
120
121 int j=1; //j的作用在于接下来的输出中每十个进行一次换行
122
123 for(int i=0;i<bytes;i++){ //遍历的时候只能到实际读取的位置处,而不是数组的长度
124
125 if(buf[i]<=0xf) System.out.print("0");
126
127 System.out.print(Integer.toHexString(buf[i])+" ");
128
129 if(j++%10==0){
130
131 System.out.println();
132
133 }
134
135 }
136
137 */
138
139 //当字节数组不够大,一次性读不完文件时我们该怎么办?
140
141 int bytes=0;
142
143 int j=1;
144
145 while((bytes=in.read(buf,0,buf.length))!=-1){
146
147 for(int i=0;i<bytes;i++){
148
149 //byte类型8位。int类型32位,为了避免类型转换错误,通过&0xff将高24位清零
150
151 if(buf[i]<=0xf){
152
153 System.out.print("0");
154
155 }
156
157 //if(buf[i]<=0xf) System.out.print("0");
158
159 System.out.print(Integer.toHexString(buf[i]&0xff)+" ");
160
161 if(j++%10==0){
162
163 System.out.println();
164
165 }
166
167 }
168
169 }
170
171 in.close();
172
173 }
174
175 /**
176
177 * 文件的拷贝
178
179 * */
180
181 public static void copyFile(File srcFile,File destFile) throws IOException{
182
183 if(!srcFile.exists()){
184
185 throw new IllegalArgumentException(srcFile+"文件不存在");
186
187 }
188
189 if(!srcFile.isFile()){
190
191 throw new IllegalArgumentException(srcFile+"不是一个文件");
192
193 }
194
195 FileInputStream in=new FileInputStream(srcFile);
196
197 FileOutputStream out=new FileOutputStream(destFile);
198
199 byte[] buf=new byte[8*1024];
200
201 int b;
202
203 while((b=in.read(buf,0,buf.length))!=-1){
204
205 //out.write(buf, 0, buf.length);
206
207 /*
208
209 * 该是写入buf.length个字节还是写入b个字节
210
211 * 写buf.length个字节一定是不恰当的,因为最终读取的时候
212
213 * buf总会出现一次未被写满的情况出现,这样copy的文件明显
214
215 * 不符合要求
216
217 *
218
219 * 在断点调试中发现即使读取的内容已经到文件的末尾没有把buf
220
221 * 数组读满read方法返回的仍是读取到的长度(也就是b)的值
222
223 * 在下次循环的时候会返回-1,也就是说 会用b来控制下次write
224
225 * 方法写入到数组中的长度才是符合要求的
226
227 *
228
229 * 说明文档中对read方法的返回值的描述:
230
231 * 读入缓冲区的字节总数,如果因为已经到达文件末尾而没有
232
233 * 更多的数据,则返回 -1。
234
235 *
236
237 * 请注意:这里说的是如果因为已经到达文件末尾而没有更多的
238
239 * 数据,也就是指当执行read方法的时候是先判断是不是到文件尾,
240
241 * 如果是到文件尾才返回-1,如果不是返回读取的字节数。而不
242
243 * 是指执行read中执行着时遇到文件尾返回-1.仔细体会一下。
244
245 * */
246
247 out.write(buf,0,b);
248
249
250
251 out.flush();
252
253 /*
254
255 * 刷新此输出流并强制写出所有缓冲的输出字节。flush 的常规协定是:
256
257 * 如果此输出流的实现已经缓冲了以前写入的任何字节,则调用此方法指
258
259 * 示应将这些字节立即写入它们预期的目标。
260
261 *
262
263 * 如果此流的预期目标是由基础操作系统提供的一个抽象(如一个文件),
264
265 * 则刷新此流只能保证将以前写入到流的字节传递给操作系统进行写入,
266
267 * 但不保证能将这些字节实际写入到物理设备(如磁盘驱动器)。
268
269 * */
270
271 }
272
273 in.close();
274
275 out.close();
276
277 }
278
279 /**
280
281 * 进行文件的拷贝,利用带缓冲的字节流
282
283 * */
284
285 public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
286
287 if(!srcFile.exists()){
288
289 throw new IllegalArgumentException(srcFile+"文件不存在");
290
291 }
292
293 if(!srcFile.isFile()){
294
295 throw new IllegalArgumentException(srcFile+"不是一个文件");
296
297 }
298
299
300
301 BufferedInputStream bis=new BufferedInputStream(
302
303 new FileInputStream(srcFile));
304
305 BufferedOutputStream bos=new BufferedOutputStream(
306
307 new FileOutputStream(destFile));
308
309 int c;
310
311 while((c=bis.read())!=-1){
312
313 bos.write(c);
314
315 bos.flush();//刷新缓冲区
316
317 }
318
319 bis.close();
320
321 bos.close();
322
323 }
324
325 public static void copyByByte(File srcFile,File destFile)throws IOException{
326
327 if(!srcFile.exists()){
328
329 throw new IllegalArgumentException(srcFile+"文件不存在");
330
331 }
332
333 if(!srcFile.isFile()){
334
335 throw new IllegalArgumentException(srcFile+"不是一个文件");
336
337 }
338
339 FileInputStream in=new FileInputStream(srcFile);
340
341 FileOutputStream out=new FileOutputStream(destFile);
342
343 int b;
344
345 while((b=in.read())!=-1){
346
347 out.write(b);
348
349 out.flush();//不是缓冲的话不写flush也是没有问题的。
350
351 }
352
353 in.close();
354
355 out.close();
356
357 }
358
359 }
测试
1 package Zhang;
2
3
4
5 import java.io.File;
6
7 import java.io.IOException;
8
9
10
11
12
13
14
15 public class IOUtilTest4 {
16
17 public static void main(String[] args) {
18
19 try {
20
21 long start=System.currentTimeMillis();
22
23 IOUtil.copyByByte(new File("/home/zhang/Desktop/1.mp3"), new File("/home/zhang/Desktop/2.mp3"));
24
25 long end=System.currentTimeMillis();
26
27 System.out.println("一个字节一个字节复制完成,用时:"+(end-start));
28
29 } catch (IOException e) {
30
31 // TODO Auto-generated catch block
32
33 e.printStackTrace();
34
35 }
36
37 try {
38
39 long start=System.currentTimeMillis();
40
41 IOUtil.copyFileByBuffer(new File("/home/zhang/Desktop/1.mp3"), new File("/home/zhang/Desktop/3.mp3"));
42
43 long end=System.currentTimeMillis();
44
45 System.out.println("缓冲复制完成,用时:"+(end-start));
46
47 } catch (IOException e) {
48
49 // TODO Auto-generated catch block
50
51 e.printStackTrace();
52
53 }
54
55 try {
56
57 long start=System.currentTimeMillis();
58
59 IOUtil.copyFile(new File("/home/zhang/Desktop/1.mp3"), new File("/home/zhang/Desktop/4.mp3"));
60
61 long end=System.currentTimeMillis();
62
63 System.out.println("批量复制完成,用时:"+(end-start));
64
65 } catch (IOException e) {
66
67 // TODO Auto-generated catch block
68
69 e.printStackTrace();
70
71 }
72
73 }
74
75 }
输出
一个字节一个字节复制完成,用时:15598
缓冲复制完成,用时:13096
批量复制完成,用时:8