本文使用了两种方法拷贝字节流文件,分别是使用byte[]数组批量读取的基于FileInputStream和FileOutputStream的方法,和使用byte[]批量读取的基于BufferedInputStream和BufferedOutputStream的方法。下面是源代码,两个方法的实现类和一个测试类。
1)
public class FileIOputStreamTest { public static void copyFile(File srcFile, File destFile) throws IOException { copyFile(srcFile, destFile, false); } public static void copyFile(File srcFile, File destFile, boolean append) throws IOException { //若源文件不存在则抛出异常 if (!srcFile.exists()) throw new IllegalArgumentException("文件:" + srcFile.getAbsolutePath() + "不存在"); if (!srcFile.isFile()) throw new IllegalArgumentException(srcFile + "不是文件"); FileInputStream in = new FileInputStream(srcFile); //若目的地文件不存在,则新建文件 File file = destFile.getParentFile(); if (!file.exists()) file.mkdirs(); FileOutputStream out = new FileOutputStream(destFile, append); byte[] buf = new byte[1024];//分配一个缓冲区 int b; while ((b = in.read(buf, 0, buf.length)) != -1) { out.write(buf, 0, b);//不这样做,结尾会有乱码,可能是最后一次写入时,buf中尾部有冗余 } in.close(); out.close(); }
}
2)
public class BufferedIOputStream { public static void copyFile(File srcFile, File destFile) throws IOException { copyFile(srcFile, destFile, false, 8*1024); } public static void copyFile(File srcFile, File destFile, boolean append,int size) throws IOException { //若源文件不存在则抛出异常 if (!srcFile.exists()) throw new IllegalArgumentException("文件:" + srcFile.getAbsolutePath() + "不存在"); if (!srcFile.isFile()) throw new IllegalArgumentException(srcFile + "不是文件"); BufferedInputStream in = new BufferedInputStream(new FileInputStream(srcFile),size); //若目的地文件不存在,则新建文件 File file = destFile.getParentFile(); if (!file.exists()) file.mkdirs(); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(destFile, append),size); byte[] buf = new byte[size];//分配一个缓冲区 int len; while ((len = in.read(buf, 0, buf.length)) != -1) { out.write(buf, 0, len);//不这样做,结尾会有乱码,可能是最后一次写入时,buf中尾部有冗余 } in.close(); out.close(); } }
3)测试类,拷贝的文件是一个847MB的电影
public class CopyTest { public static void main(String[] args) { File src = new File("E:\\个人\\电影\\驯龙高手BD中英双字.rmvb"); File dest = new File("C:/users/赵/desktop/电影.rmvb"); try { long start = System.currentTimeMillis(); FileIOputStreamTest.copyFile(src, dest); long end = System.currentTimeMillis(); System.out.println(end - start); start = System.currentTimeMillis(); BufferedIOputStream.copyFile(src, dest,false,20*1024*1024); end = System.currentTimeMillis(); System.out.println(end - start); } catch (IOException e) { e.printStackTrace(); } } }
最终测试结果,输出为31021ms,8409ms。
如果不分配byte[]作为缓冲区的话,速度会非常慢,不信的可以自己测试,window系统下5400转8M缓存的硬盘直接复制大概五秒,还是快。