能悟能
2016-04-03 22:28
之前看老师试了copyFile 和copyFileByBuffered,发现copyFile要快,然后自己去测试,就发现
读取速度byte[] buf=new byte[8*1024];和这个有关,我往上调了,那么这两个优劣在哪里
同样条件下,是应该Buffer比普通的读取快,但不是最快的,最快是用FileInputStream的getChannel()方法去读取。你可以运行下面的那段代码去对比下就知道了。
package imooc.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; public class CopyFileTest { /** * @param args */ public static void main(String[] args) { try { Long start,end; start = System.currentTimeMillis(); copyFileNormal(new File("D:\\javaio\\1.mp3"),new File("D:\\javaio\\2.mp3")); end = System.currentTimeMillis(); System.out.println("运行copy file 的普通方法需要的时间是: " + (end - start) + "毫秒"); start = System.currentTimeMillis(); copyFileBuffer(new File("D:\\javaio\\1.mp3"),new File("D:\\javaio\\3.mp3")); end = System.currentTimeMillis(); System.out.println("运行copy file 的buffer普通方法需要的时间是: " + (end - start) + "毫秒"); start = System.currentTimeMillis(); copyFileChannel("D:\\javaio\\1.mp3","D:\\javaio\\4.mp3"); end = System.currentTimeMillis(); System.out.println("运行copy file 的getChannel()方法需要的时间是: " + (end - start) + "毫秒"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //copy file 的普通方法 public static void copyFileNormal(File inFile, File outFile) throws IOException{ FileInputStream fis = new FileInputStream(inFile); FileOutputStream fos = new FileOutputStream(outFile); byte[] buf = new byte[1024]; int len = 0; while((len = fis.read(buf)) != -1){ fos.write(buf, 0, len); fos.flush(); } fis.close(); fos.close(); } //copy file 的buffer普通方法 public static void copyFileBuffer(File inFile, File outFile) throws IOException{ BufferedInputStream buffis = new BufferedInputStream( new FileInputStream(inFile)); BufferedOutputStream buffos = new BufferedOutputStream( new FileOutputStream(outFile)); byte[] buf = new byte[1024]; int len = 0; while((len = buffis.read(buf)) != -1){ buffos.write(buf, 0, len); buffos.flush(); } buffis.close(); buffos.close(); } //copy file 的getChannel()方法 public static void copyFileChannel(String inFile, String outFile) throws IOException{ FileInputStream fis = new FileInputStream(inFile); FileOutputStream fos = new FileOutputStream(outFile); FileChannel fcin = fis.getChannel(); FileChannel fcout = fos.getChannel(); fcin.transferTo(0, fcin.size(), fcout); fis.close(); fos.close(); fcin.close(); fcout.close(); } }
下面是运行结果:
运行copy file 的普通方法需要的时间是: 94毫秒
运行copy file 的buffer普通方法需要的时间是: 62毫秒
运行copy file 的getChannel()方法需要的时间是: 16毫秒
这个问题首先要明白,读取和写入的过程;
知道运行内存吧???计算机为什么要运行内存呢???其实运行内存就是一个缓冲区!!
文件的读取和写入操作的过程是这样的:
(1)首先说一下批量读取和单个字节的读取
批量读取是new一个对象,new一个对象就是在内存中申请一个和new的要求的大小相一致的运行内存;
单个读取系统默认申请了一个字节的运行内存;
(2)文件的读取和写入
1.先说单个字节的读取,从原文件中读取一个字节放入到内存中,再从内存中把一个字节大小的数据放入到目标文件中;(强调一次操作必须是直接从源文件到内存再到目标文件, 才能再次读取下个字节)
2.再说批量读取,同理
从原文件中读取多个字节放入到内存中,再从内存中把多个字节大小的数据放入到目标文件中;(强调一次操作必须是直接从源文件到内存再到目标文件, 才能再次读取下多字节)
(3)从2中我们就能理解Buffer的运行机制了,开始解释(再强调一下运存既是缓存区)
buffer的单个读取,同理读取既是先读取一个字节放入内存中,在读取一个字节中,直到读取完整个文件,批量从缓存中放到目标文件中,可以看粗这样节省了一次一次的从内存中到目标文件的过程即(1——》2——》3变成了1——》3,这样从需要花费2步,变成只花费了一步,所以buffer的性能应该是正常的一倍)
buffer的批量读取,同理读取既是先读取多个字节放入内存中,在读取多个字节中,直到读取完整个文件,批量从缓存中放到目标文件中,可以看粗这样节省了一次一次的从内存中到目标文件的过程即(1——》2——》3变成了1——》3,这样从需要花费2步,变成只花费了一步,所以buffer的性能应该是正常的一倍)
(4)总结,累死我了,以上内容纯属自己瞎想,没有验证,求大神验证,告诉我答案,
我是渣渣,我是新手,验证发现我说的错了,请不要骂我,xiexie
我认为buffered缓冲与byte[]数组搭配使用最快,如果把复制比作水换缸,byte[]相当于用瓢舀水,buffered相当于用水桶转移水,单用瓢或者单用桶都不如组合使用效率高.之所以视频中buffered比byte[]慢,我认识是因为循环每次都flush了buffered缓冲区,造成一瓢水刚舀进桶里就拿着桶去转移这一瓢水了,完全没有等桶满了,没有体现出缓冲区缓冲的作用,而白白浪费了运算buffered的时间,在循环结束后再flush buffered缓冲区用时会大大减少.推荐去看看极客学院这节视频,你就明白搭配使用的优点了.
------以上纯属新手见解,恳请大神指正.
如果用带缓冲批量字节读取那么速度一定比不带缓冲批量字节读取的速度快
文件传输基础——Java IO流
133754 学习 · 1030 问题
相似问题