java中IO流分为字节流和字符流,其中字节流为InputStream和OutputStream,字符流为writer和reader。今天我们就来谈谈哪种方法拷贝文件效率最高。
方法一:
public static void main(String[] args) throws IOException { //创建输入流,并从file.txt文件中读出数据 FileInputStream fileInputStream = new FileInputStream("file.txt"); //创建输出流,并将读出的数据写入到copy.txt中,如果没有copy.txt则创建,有则先清空里面的内容然后再写入 FileOutputStream fileOutputStream = new FileOutputStream("copy.txt"); //按字节逐个读出,再逐个写出 int b; while ((b = fileInputStream.read()) != -1) { //-1为文件结束的标记 fileOutputStream.write(b); } //关闭资源 fileInputStream.close(); fileOutputStream.close(); }
此种方法的效率是很低的,实际开发中一般不使用。因为read()方法是按字节读出,也就是说从文件中一个字节一个字节的读出数据,然后再一个字节一个字节写入文件。当文件较大时,它的弊端就很明显了。
方法二:
public static void main(String[] args) throws IOException { // 创建输入流,并从file.txt文件中读出数据 FileInputStream fileInputStream = new FileInputStream("file.txt"); // 创建输出流,并将读出的数据写入到copy.txt中,如果没有copy.txt则创建,有则先清空里面的内容然后再写入 FileOutputStream fileOutputStream = new FileOutputStream("copy.txt"); //available()获取文件中总的字节数 int b = fileInputStream.available(); //创建一个字节数组arr byte[] arr = new byte[b]; //将文件中的数据一次性读出,存储到arr中 fileInputStream.read(arr); //将arr中的数据一次性写入到文件中 fileOutputStream.write(arr); // 关闭资源 fileInputStream.close(); fileOutputStream.close(); }
此种方法效率是很高的,首先它创建一个和文件一样大小的字节数组。用来存储数据,然后从文件中一次性读出。然后再将数组中的数据一次性写入文件中。但是,此种方法的弊端也是挺大的,因为当文件较大时,文件的总字节数也很大。容易造成内存溢出。实际开发中一般也不用。
方法三:
public static void main(String[] args) throws IOException { // 创建输入流,并从file.txt文件中读出数据 FileInputStream fileInputStream = new FileInputStream("file.txt"); // 创建输出流,并将读出的数据写入到copy.txt中,如果没有copy.txt则创建,有则先清空里面的内容然后再写入 FileOutputStream fileOutputStream = new FileOutputStream("copy.txt"); //创建一个字节数组,大小一般为1024的整数倍 byte[] arr = new byte[1024*10]; int len; //每次循环读取数组arr中的数据,再写入到文件中 while ((len = fileInputStream.read(arr)) != -1) { fileOutputStream.write(arr, 0, len); } // 关闭资源 fileInputStream.close(); fileOutputStream.close(); }
此种方法效率高,而且安全,为实际开发中常用方法。它并不是一次性将文件中的全部数据读取,而是通过创建一个小的字节数组,数组大小一般为1024的整数倍,一次性读取数组大小的数据。read(arr)返回的时读取到的有效字节数。writer(arr,0,len)表示将数组arr中的数据写出,下标从0开始,写len个字节。
方法四:
public static void main(String[] args) throws IOException { //创建缓冲区输入流,并从file.txt文件中读出数据 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("file.txt")); //创建缓冲区输出流,并从copy.txt文件中写入数据 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("copy.txt")); int b; while ((b = bufferedInputStream.read()) != -1) { bufferedOutputStream.write(b); } // 关闭资源 bufferedInputStream.close(); bufferedOutputStream.close(); }
此种方法实际开发中也用的比较多。效率也很高,但略低于方法三。此种方法借助了缓冲区输入流和输出流来拷贝文件。BufferedInputStream类包装了FileInputStream类,它内部创建了一个小的字节数组来存储从文件读取的数据。它首先从文件中读取数组大小的数据,然后再一个一个字节的读取出来,再一个一个字节的写入到BufferedOutstream中的小字节数组中。当
数组存满后再写入到文件中。虽然这里也是一个一个字节读取和写入,但这是在内存中进行的。方法一是一个一个字节从硬盘读取到内存。明显效率是很低的。因为内存的运算效率远高于硬盘。跟方法三相比,效率却稍低一些,因为方法三读出和写入都只通过一个数组来实现。而此种方法却是通过两个数组来实现。