1、字节流
在 Java 中,文件的复制使用字节输入流和字节输出流实现,java.io 包有 InputStream 和 OutputStream 这两个顶层抽象类规范了读写文件所需的核心 API。
我们可以使用它们的子类 FileInputStream 和 FileOutputStream 来编写程序复制文件。
第一种方式:
使用 read() 和 write() 方法配合循环操作单字节的读取、写入
InputStream 的 read() 会尝试从文件读取一个字节,如果到了文件结尾则会返回-1
第二种方式:
使用 read(byte[]) 和 write(byte[], int, int) 方法配合字节缓冲、循环操作实现高效的读取、写入
InputStream 的 read(byte[]) 会尝试从文件读取 byte[] 长度个字节,该方法会把具体读取到的字节数返回,如果到了文件结尾则会返回 -1
OutputStream 的 write(byte[] buf, int offest, int len) 方法会把 buf 数组中从偏移量 offest 开始的 len 个字节写到输出流
2、单字节读写
1 private static void copyFile(String src, String dst) throws IOException {
2
3 // 用于计算程序运行时间
4 long start = System.currentTimeMillis();
5
6 // 定义输入流和输出流
7 FileInputStream fis = null;
8 FileOutputStream fos = null;
9 try {
10
11 // 实例化输入流和输出流
12 fis = new FileInputStream(src);
13 fos = new FileOutputStream(dst);
14
15 int i = fis.read();
16
17 // 循环从输入流读取字节,直到读取到-1即文件结尾
18 while(i != -1) {
19 fos.write(i); // 写出到输出流
20 i = fis.read();
21 }
22 } catch (IOException e) {
23 // 需要捕获IOException
24 e.printStackTrace();
25 throw e;
26 } finally {
27 // 在finally代码块关闭IO流
28 try {
29 if (fis != null)
30 fis.close();
31 if (fos != null)
32 fos.close();
33 } catch (IOException e) {}
34 }
35
36 // 计算程序运行时间
37 long end = System.currentTimeMillis();
38 System.out.println(end - start);
39 }
3、定义缓冲高效读写
1 private static void bufferedCopyFile(String src, String dst) throws IOException {
2
3 // 用于计算程序运行时间
4 long start = System.currentTimeMillis();
5
6 // 定义输入流和输出流
7 FileInputStream fis = null;
8 FileOutputStream fos = null;
9 try {
10
11 // 实例化输入流和输出流
12 fis = new FileInputStream(src);
13 fos = new FileOutputStream(dst);
14
15 // 定义一个字节缓冲数组
16 byte[] buf = new byte[1024];
17 int i = fis.read(buf);
18
19 // 循环从输入流尝试读取buf长度的字节存放到buf中
20 while(i != -1) {
21 fos.write(buf, 0, i); // 把buf写到输出流
22 i = fis.read(buf);
23 }
24 } catch (IOException e) {
25 // 需要捕获IOException
26 e.printStackTrace();
27 throw e;
28 } finally {
29 // 在finally代码块关闭IO流
30 try {
31 if (fis != null)
32 fis.close();
33 if (fos != null)
34 fos.close();
35 } catch (IOException e) {}
36 }
37 // 计算程序运行时间
38 long end = System.currentTimeMillis();
39 System.out.println(end - start);
40 }
4、程序运行
1 public static void main(String[] args) {
2 String src = "D:\\src.bmp";
3 String dst = "D:\\tmp\\java\\dst.bmp";
4
5 try {
6
7 // 单字节读写
8 copyFile(src, dst);
9
10 // 定义缓冲高效读写
11 bufferedCopyFile(src, dst);
12 } catch (IOException e) {
13 e.printStackTrace();
14 }
15 }
输出:
21092
162
可以看到定义了缓冲区的方法要比单字节地读写效率高很多