四种字节流复制文件的效率比较

来源:互联网 发布:linux卸载软件 yum 编辑:程序博客网 时间:2024/06/06 00:49

单个字节读取后再写入到流中的方式太慢了,暂且不讨论之(main函数中已经注释掉了)。

其实通过阅读bufferedoutputstream的源码我们可以知道, bufferedoutputstream实际上就是提供了一个数组来缓冲数据,而在方式二中,我们同样提供了一个数组来缓冲数据,将读取到的数据先存到数组中。一开始,方式二与方式四用于接收读取的到的数据的数组长度都是1024,运行之后,确实是用了缓冲输出流的方法四比较快,这让我觉得很是奇怪,缓冲输出流的原理确实使用数组缓存数据,然后积累到一定程度就写入到流中啊,为什么同样的原理缓冲输出流就是快呢。

后来我意识到,缓冲输出流中,默认的缓存数组是8k(8192字节),如果需要复制的数据足够大,那么缓冲输出流每次都是等到数组满了,也就是有了8K的数据之后,才向流中写入。而方式二的就只有1024,每次1k满了,就向流中写入数据,这样跟系统交互的次数自然多了很多。当我把方式二的数组增加到同样是8192的时候,再运行,方式二的速度反而是比方式四快了。我想原因应该是方式四里,相当于进行了多次缓冲,这样就导致了执行的效率低了一些。

package exercise01;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;/* * 四种字节流复制文件的效率比较可以用System.currentTimeMillis()来获取系统的时间 */public class CopyTest {public static void main(String[] args) throws IOException {// TODO Auto-generated method stubString scName = "1024.rmvb";File javaSource = new File("D:\\111\\"+scName);File javaTargetByte = new File("D:\\222\\Byte"+scName);File javaTargetBytes = new File("D:\\222\\Bytes"+scName);File javaTargetbuffer = new File("D:\\222\\Buffer"+scName);File javaTargetbuffers = new File("D:\\222\\Buffers"+scName);//fileByte(javaSource,javaTargetByte);//方式一fileBytes(javaSource,javaTargetBytes);//方式二//bufferedByte(javaSource,javaTargetbuffer);//方式三bufferedBytes(javaSource,javaTargetbuffers);//方式四}//方式一:读取单个字节,输出单个字节public static void fileByte(File source, File target) throws IOException {long start = System.currentTimeMillis();FileInputStream fis = new FileInputStream(source);FileOutputStream fos = new FileOutputStream(target);int data;while((data = fis.read())!= -1) {fos.write(data);}fis.close();fos.close();long end = System.currentTimeMillis();System.out.println("单字节读取及输出,复制一个Java文件耗时 "+(end - start)+" 毫秒");}//方式二:用数组存储读取到的字节数据,然后写入public static void fileBytes(File source, File target) throws IOException {long start = System.currentTimeMillis();FileInputStream fis = new FileInputStream(source);FileOutputStream fos = new FileOutputStream(target);byte[] data = new byte[1024];int len;while((len = fis.read(data))!=-1) {fos.write(data, 0, len);}fis.close();fos.close();long end = System.currentTimeMillis();System.out.println("多字节读取及输出,复制一个Java文件耗时"+(end - start)+"毫秒");}//方式三:使用缓冲输入流按字节读取及缓冲输出流来复制public static void bufferedByte(File source, File target) throws IOException {long start = System.currentTimeMillis();FileInputStream fis = new FileInputStream(source);FileOutputStream fos = new FileOutputStream(target);BufferedInputStream bis = new BufferedInputStream(fis);BufferedOutputStream bos = new BufferedOutputStream(fos);int data;while((data = bis.read())!=-1) {bos.write(data);}bis.close();bos.close();long end = System.currentTimeMillis();System.out.println("使用缓冲输入流读取单字节,缓冲输出流来复制,耗时"+(end - start)+"毫秒");}//方式四:使用缓冲输入流及缓冲输出流来复制public static void bufferedBytes(File source, File target) throws IOException {long start = System.currentTimeMillis();FileInputStream fis = new FileInputStream(source);FileOutputStream fos = new FileOutputStream(target);BufferedInputStream bis = new BufferedInputStream(fis);BufferedOutputStream bos = new BufferedOutputStream(fos);byte[] data = new byte[1024];int len;while((len = bis.read(data))!=-1) {bos.write(data,0,len);}bis.close();bos.close();long end = System.currentTimeMillis();System.out.println("使用缓冲输入流读取单字节,缓冲输出流来复制,耗时"+(end - start)+"毫秒");}}



原创粉丝点击