class CopyFile {
public static void main(String args[]) throws IOException{
int i
FileInputStream fin=null//定义文件字节输入流对象
FileOutputStream fout=null//定义文件字节输出流对象
if(args.length<2){
System.out.println("用法:copy 源文件 目标文件")
return
}
try{
fin=new FileInputStream(args[0])//创建文件字节输入流
}catch(FileNotFoundException e){
System.out.println("源文件未找到")
return
}
try{
fout=new FileOutputStream(args[1])//创建文件字节输出流
}catch(FileNotFoundException e){
System.out.println("创建目标文件出错")
return
}
try{
// byte[] j=new byte[10]//每次传输10个字节
// while((i=fin.read(j))!=-1)
// fout.write(j)
while((i=fin.read())!=-1)
fout.write(i)
}catch(IOException e){
System.out.println("源文件复制出错")
return
}
fin.close()//关闭输出流
fout.close()//关闭输入流
}
}
尽管Java提供了 java.io.File 这样一个 *** 作文件的类,但并没有提供一个复制文件的方法。
然而,当我们需要对磁盘上的文件进行处理的时候,这是一个很重要的方法。在这个时候我们往往不得不自己实现这样一个完成文件复制 *** 作的方法。下面将会介绍4种常见的文件复制的实现,并比较下它们的性能。
能找到的最常见经典例子。从文件A的输入流读取一批字节,写到文件B的输出流。
如你所见,这种实现方式需要多次读取数据,再写入将数据写入,因此受限于我们提供的buffer的大小,他的效率有点一般。
Java NIO类库里引入了一个叫 transferFrom 的方法,文档里说这是一个会比 FileStream 方式更快的复制 *** 作。
Appache Commons IO 提供了一个 FileUtils.copyFile(File from, File to) 方法用于文件复制,如果项目里使用到了这个类库,使用这个方法是个不错的选择。它的内部也是使用Java NIO的 FileChannel 实现的。
如果对Java 7 的使用有经验的话,那应该接触过 Files 这个工具类。
由于项目里没用到 Apache Common IO ,Android仅支持 Java 7 的语法特性,因此我只测试了前两种,数据如下:
复制文件,大小2M
复制文件,大小4.5M
复制文件,大小8M
复制文件,大小161M
从数据上可以看出,使用 FileStream 的方式,复制的效率跟我们的buffer大小取值关系很大,这无疑加大了我们使用它进行文件复制的负担。
而NIO的方式则不然,无论是小文件、还是大文件,它的效率都跟我们测试 FileStream 的最好水平相当!
因此,把 FileStream 这种老旧的实现方式从项目里挪走吧,是时候用上 FileChannel 了。
2016年06月16日 14:04 更新
大致就是从输入里映射一部分作为buffer,写到输出去,Buffer的大小最大为8388608,如果剩余的文件长度小于这个值,则用剩余文件长度的大小为buffer大小,继续写入,直到完全写完。
需要注意到的是,buffer并不是我们平时使用的byte数组,而是 MappedByteBuffer 对象,这是 java nio 引入的文件内存映射方案,读写性能很高。
这里以字节流FileInputStream,FileOutputStream为例。代码例子如下:
import java.io.File/**
* 把一个文件夹中的文件复制到一个指定的文件夹
* @author young
*
*/
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
public class CopyFile {
public static void main(String[] args) {
/* 指定源exe文件的存放路径 */
String str = "f:/jdk-1_5_0_06-windows-i586-p.exe"
/* 指定复制后的exe的目标路径 */
String strs = "e:/copy.exe"
/* 创建输入和输出流 */
FileInputStream fis = null
FileOutputStream fos = null
try {
/* 将io流和文件关联 */
fis = new FileInputStream(str)
fos = new FileOutputStream(strs)
byte[] buf = new byte[1024 * 1024]
int len
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len)
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
} finally {
try {
fis.close()
fos.close()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
}
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)