Java文件操作

1  Java文件操作之文件复制

Java中实现文件复制一共有四种方法,方法不同,自然效率也不同。

1.1  第一种方法:原始方式

 1 import java.io.*;//需要导入IO类
 2 /***下面的只是一个方法***/
 3 public static long forJava(File f1,File f2) throws Exception{//定义文件复制方法
 4     int length=2097152;//定义字节大小,大小为2M
 5     FileInputStream in=new FileInputStream(f1);//由f1创建一个输入流
 6     FileOutputStream out=new FileOutputStream(f2);//由f2创建一个输出流
 7     byte[] buffer=new byte[length];//定义字节数组
 8     while(true){//进入死循环
 9         int ins=in.read(buffer);//将f1代表的文件读到数组中,并获取长度
10         if(ins==-1){//如果文件大小不存在
11             in.close();//关闭输入流
12             out.flush();//彻底完成输出,并清空缓存区
13             out.close();//关闭输出流
14         }else//否则
15             out.write(buffer,0,ins);//将数组中的内容写到输出流
16     }
17 }

此为不完整代码,只定义一个方法,用的时候直接调用即可。这种方法实现较为简单,分别对两个文件构造输入输出流,并使用一个字节数组作为缓存器,然后使用流从文件f1中读取数据到缓存器,缓存器能存储的最大文件大小为2M,再把缓存器中的内容写到目标文件f2中。

1.2  第二种方法:使用NIO中的管道传输

 1 import java.io.*;//导入文件类
 2 import java.nio.channels.FileChannel;//需要导入NIO类
 3 /***下面的只是一个方法***/
 4 public static long forTransfer(File f1,File f2) throws Exception{
 5     int length=2097152;
 6     FileInputStream in=new FileInputStream(f1);
 7     FileOutputStream out=new FileOutputStream(f2);
 8     FileChannel inC=in.getChannel();
 9     FileChannel outC=out.getChannel();
10     while(true){
11         if(inC.position()==inC.size()){
12             in.close();
13             out.close();
14             inC.close();
15             outC.close();
16         }
17         if((inC.size()-inC.position())<20971520)
18             length=(int)(inC.size()-inC.position());
19         else
20             length=20971520;
21         inC.transferTo(inC.position(),length,outC);
22         inC.position(inC.position()+length);
23     }
24 }

此种方法主要是在第一种方法的基础上对输入输出流获得其管道,然后分批次的从f1的管道中向f2的管道中输入数据,每次输入的数据最大为2M。

1.3  第三种方法:内存文件镜像

 1 import java.io.*;//导入文件类
 2 import java.nio.MappedByteBuffer;
 3 import java.nio.channels.FileChannel;
 4 import java.nio.channels.FileChannel.MapMode;
 5 /***下面的只是一个方法***/
 6 public static long forImage(File f1,File f2) throws Exception{
 7     int length=2097152;
 8     FileInputStream in=new FileInputStream(f1);
 9     RandomAccessFile out=new RandomAccessFile(f2,"rw");
10     FileChannel inC=in.getChannel();
11     MappedByteBuffer outC=null;
12     MappedByteBuffer inbuffer=null;
13     byte[] b=new byte[length];
14     while(true){
15         if(inC.position()==inC.size()){
16             in.close();
17             out.close();
18             inC.close();
19             outC.force();                
20         }
21         if((inC.size()-inC.position())<length){
22             length=(int)(inC.size()-inC.position());
23         }else{
24             length=20971520;
25         }
26         b=new byte[length];
27         inbuffer=inC.map(MapMode.READ_ONLY,inC.position(),length);
28         inbuffer.load();
29         inbuffer.get(b);
30         outC=out.getChannel().map(MapMode.READ_WRITE,inC.position(),length);
31         inC.position(b.length+inC.position());
32         outC.put(b);
33         outC.force();
34     }
35 }

此方法写文件流中没有用到管道,而是使用内存文件映射(假设文件f2在内存中),在循环中从f1的管道中读取数据到字节数组中,然后再向内存映射f2文件中写数据。

1.4  第四种方法:管道对管道

 1 import java.io.*;//导入文件类
 2 import java.nio.ByteBuffer;
 3 import java.nio.channels.FileChannel;
 4 /***下面的只是一个方法***/
 5 public static long forChannel(File f1,File f2) throws Exception{
 6     int length=2097152;
 7     FileInputStream in=new FileInputStream(f1);
 8     FileOutputStream out=new FileOutputStream(f2);
 9     FileChannel inC=in.getChannel();
10     FileChannel outC=out.getChannel();
11     ByteBuffer b=null;
12     while(true){
13         if(inC.position()==inC.size()){
14             in.close();
15             out.close();
16             inC.close();
17             outC.close();
18         }
19         if((inC.size()-inC.position())<length){
20             length=(int)(inC.size()-inC.position());
21         }else
22             length=2097152;
23         b=ByteBuffer.allocateDirect(length);
24         inC.read(b);
25         b.flip();
26         outC.write(b);
27         outC.force(false);
28     }
29 }

该方法和第三种方法相似,不过没有使用内存映射。

1.5  总结

如果利用时间类获取程序运行的时间,可以发现,对于同一个文件,第一种方法和第四种方法是运行速度最快的,尤其是第四种方法。原因可能是另外两种方法中都有字节数组作为缓存器,再加上NIO内部有一个贴近系统的缓存器,这无疑相当于两个缓存器了,所以相对就慢很多。

【注】以上部分来源于 Java实现文件拷贝的4种方法,经本人稍作修改。

2  Java文件操作之文件移动

移动文件到指定目录,并不是复制后再删除源文件,而是使用renameTO方法实现

 1 import java.io.File;//导入文件类
 2 public class GCXL21K3 {//主类
 3     public static void main(String[] args) {//主方法
 4         try {//异常处理
 5             File afile = new File("E:\\word.txt");//创建文件对象
 6             if(afile.renameTo(new File("D:\\" + afile.getName()))){//执行复制命令
 7                 System.out.println("File is moved successful!");//输出成功
 8             }else{//否则
 9                 System.out.println("File is failed to move!");//输出失败
10             }
11         }catch(Exception e){//异常处理
12             e.printStackTrace();//输出异常信息
13         }
14     }
15 }

在JDK手册中,这样介绍renameTO方法:

renameTO(File dast)  重新命名此抽象路径名表示的文件

posted @ 2018-01-14 21:39  祁俊辉  阅读(152)  评论(0编辑  收藏  举报