工具/原料
一台配置了java环境的电脑
一款适合自己的开发集成环境,这里用的是eclipse Kepler
文件拷贝DEMO
1.首先,理清思路,然后我们再动手 *** 作。
拷贝,有源文件,和目的文件。
如果原文件不存在,提示,报错。
如果目的文件不存在,创建空文件并被覆盖。
如果目的地址,也即目的路径不存在,创建路径。
拷贝,输入流,输出流,关闭流。
拷贝前输出文件大小,计算拷贝大小,比较并核实。输出。
2.首先呢,先判断传参是否完整。
如果不够两个参数,或者多于两个参数,提示错误。
如果目标文件不存在,创建 空文件继续复制。
3.在开始前,输出被拷贝的源文件的大小。
4.获得文件名称,即短名。也即路径下的文件全名(包括文件扩展名)。
5.拷贝的关键,这里用的简单的缓冲流。从源文件到目的文件。
number of bytes copied 即是对拷贝长度的累计,直到拷贝完成,输出。
6.将步骤二中的判断并拷贝文件的代码写在一个main函数中,
执行拷贝,拷贝完成。结果拷贝大小和源文件大小一致,成功。
7.在执行前,记得输入参数。
如果是使用命令提示符,执行 javac CopyFile.java 之后,
执行 java CopyFile [源文件长名] [目的文件长名]
如果是使用的eclipse,在运行前设置一下运行参数,完成后点击运行,如下图。
P.S. 这里面的所谓“长名”是指完整绝对路径+文件名+文件类型扩展名
这里的源文件及目的文件的名称分别为:
E:/IP_Data.rar 和 D:/testFiles/IP_Data.rar
END
尽管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 引入的文件内存映射方案,读写性能很高。
Java代码
/**
* // 从旧文件拷贝内容到新文件
* // 删除旧文件
* @param oldPath the path+name of old file
* @param newPath the path+name of new file
* @throws Exception
*/
private void transferFile(String oldPath String newPath) throws Exception {
int byteread =
File oldFile = new File(oldPath)
FileInputStream fin = null
FileOutputStream fout = null
try{
if(oldFile exists()){
fin = new FileInputStream(oldFile)
fout = new FileOutputStream(newPath)
byte[] buffer = new byte[ ]
while( (byteread = fin read(buffer)) != ){
logger debug( byteread== +byteread)
fout write(buffer byteread)
}
if(fin != null){
fin close()//如果流不关闭 则删除不了旧文件
this delFile(oldFile)
}
}else{
throw new Exception( 需要转移的文件不存在! )
}
}catch(Exception e){
e printStackTrace()
throw e
}finally{
if(fin != null){
fin close()
}
}
}
/**
* 删除文件 只支持删除文件 不支持删除目录
* @param file
* @throws Exception
*/
private void delFile(File file) throws Exception {
if(!file exists()) {
throw new Exception( 文件 +file getName()+ 不存在 请确认! )
}
if(file isFile()){
if(file canWrite()){
file delete()
}else{
throw new Exception( 文件 +file getName()+ 只读 无法删除 请手动删除! )
}
}else{
throw new Exception( 文件 +file getName()+ 不是一个标准的文件 有可能为目录 请确认! )
}
lishixinzhi/Article/program/Java/hx/201311/25584
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)