您的位置:首页 > 编程语言 > Java开发

Java_IO_两种文件复制方式比较

2017-04-24 17:53 573 查看

一:缓冲输入输出流(InputStream、OutputStream)

[java] view
plain copy

 print?





<span style="font-size:14px;">    /* 

     *缓冲输入输出流方式复制文件  

     */  

    public static boolean copyFile(String srcFileName,String destFileName,boolean overlay){  

            File srcFile = new File(srcFileName); //根据一个路径得到File对象  

            //判断源文件是否存在  

            if(!srcFile.exists()){  

                try{  

                    throw new Exception("源文件:"+srcFileName+"不存在!");  

                }catch(Exception e){  

                    e.printStackTrace();//将异常内容存到日志文件中  

                }  

                return false;  

            }else if(!srcFile.isFile()){//判断是不是一个文件  

                try {  

                    throw new Exception("复制文件失败,源文件:"+srcFileName+"不是一个文件!");  

                } catch (Exception e) {  

                  

                    e.printStackTrace();  

                }  

                return false;  

                  

            }  

            //判断目标文件是否存在  

            File destFile = new File(destFileName);//目标文件对象destFile  

            if(destFile.exists()){  

                //如果目标文件存在并允许覆盖  

                if(overlay){  

                    //删除已经存在的目标文件  

                    new File(destFileName).delete();  

                      

                }  

            }else{  

                //如果目标文件所在目录不存在,则创建 目录  

                if(!destFile.getParentFile().exists()){  

                    //目标文件所在目录不存在  

                    //mkdirs():创建此抽象路径名指定的目录,包括所有必需但不存在的父目录  

                    if(!destFile.getParentFile().mkdirs()){  

                        //复制文件失败:创建目标文件所在目录失败  

                        return false;  

                    }  

                }  

            }  

              

            //复制文件  

            int byteread = 0;//读取的字节数  

            InputStream  in = null;  

            OutputStream  out = null;  

              

            try {  

                in  = new FileInputStream(srcFile);  

                out = new FileOutputStream(destFile);  

                byte[] buffer = new byte[1024];  

                /* 

                 * 方法说明: 

                 * ①:将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 

                 *      write(byte[] b, int off, int len)  

                 *          b - 数据 

                 *          off - 数据中的起始偏移量。 

                 *          len - 要写入的字节数。  

                 * ②:in.read(buffer))!=-1,是从流buffer中读取一个字节,当流结束的时候read返回-1 

                 */  

  

                while((byteread = in.read(buffer))!=-1){  

                    out.write(buffer, 0, byteread);  

                }  

                return true;  

            } catch (FileNotFoundException e) {  

                  

                return false;  

            } catch (IOException e) {  

                return false;  

            }finally{  

                try {  

                    if(out!=null){  

                        out.close();  

                    }  

                    if(in!=null){  

                        in.close();  

                    }  

                } catch (IOException e) {  

                      

                    e.printStackTrace();  

                }  

            }  

    }</span>  

二:文件通道(FileChannel)

[java] view
plain copy

 print?





<span style="font-size:14px;">    /* 

     * 使用文件通道的方式复制文件 

     */  

    public static void fileChannelCopy(String srcDirName,String destDirName){  

        FileInputStream fi = null;  

        FileOutputStream fo = null;  

        FileChannel in = null;  

        FileChannel out = null;  

          

        try {  

            fi = new FileInputStream(new File(srcDirName));  

            fo = new FileOutputStream( new File(destDirName));  

            in = fi.getChannel();//得到对应的文件通道  

            out = fo.getChannel();//得到对应的文件通道  

            /* 

             *       public abstract long transferTo(long position, long count, 

                                         WritableByteChannel target)throws IOException; 

             *          position - 文件中的位置,从此位置开始传输;必须为非负数   

             *          count - 要传输的最大字节数;必须为非负数   

             *          target - 目标通道    

             *          返回:   

                        实际已传输的字节数,可能为零   

             */  

            in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道中  

        } catch (FileNotFoundException e) {  

          

            e.printStackTrace();  

        } catch (IOException e) {  

          

            e.printStackTrace();  

        }finally{  

            try {  

                fi.close();  

                in.close();  

                fo.close();  

                out.close();  

            } catch (IOException e) {  

                  

                e.printStackTrace();  

            }  

        }  

          

    }</span>  

测试上面的两个方法:

[java] view
plain copy

 print?





<span style="font-size:14px;">public class copyFile{  

    public static void main(String[] args) {  

        String srcDirName = "E:/360cse_official.exe";//待复制的文件名  

        String destDirName ="E:/360cse_official_test.exe";//目标文件名  

        long start;  

        long end;  

        start = System.currentTimeMillis();//返回系统的当前时间  

        copyFile.copyFile(srcDirName,destDirName,true);  

        end = System.currentTimeMillis();  

        System.out.println("缓冲输入输出流方式复制文件,用时:"+(end-start)+"ms");  

          

        start = System.currentTimeMillis();  

        copyFile.fileChannelCopy(srcDirName,destDirName);  

        end = System.currentTimeMillis();  

        System.out.println("使用文件通道的方式复制文件,用时:"+(end-start)+"ms");  

          

    }</span>  

测试文件:



运行结果:
缓冲输入输出流方式复制文件,用时:499ms

使用文件通道的方式复制文件,用时:57ms

总结:

通过对上面两个方法测试,我们可以知道使用文件通道的方式复制文件,明显比输出流复制文件效率要高。
学到的知识点:

①:返回系统的当前时间:start = System.currentTimeMillis();
②:write(byte[] b, int off, int len) 方法

将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流

b - 数据
off - 数据中的起始偏移量。
len - 要写入的字节数。 

③:in.read(buffer))!=-1,是从流buffer中读取一个字节,当流结束的时候read返回-1
④:in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道中

public abstract long transferTo(long position, long count,
            WritableByteChannel target)throws IOException;
position - 文件中的位置,从此位置开始传输;必须为非负数  
count - 要传输的最大字节数;必须为非负数  
target - 目标通道   
返回:  
实际已传输的字节数,可能为零  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java