copy file 性能优化

 

 BufferedInputStream/BufferedOutputStream
 内存的运算效率比硬盘快很多,所以只有降低硬盘的读取次数才会提高效率。

 file_old  --  BufferedInputStream(1024 * 8)  --  BufferedOutputStream(buffer:1024 * 8) -- file_new
 程序向流中写出字节时,不会直接写到文件中,会先写到缓冲区中,直到缓冲区写满,才会把缓冲区中的数据一次性写到文件中  flush。
 

1. FileOutputStream   普通

private static void customBufferStreamCopy(File source, File target) {  
    InputStream fis = null;  
    OutputStream fos = null;  
    try {  
        fis = new FileInputStream(source);  
        fos = new FileOutputStream(target);  
        byte[] buf = new byte[4096];  
        int i;  
        while ((i = fis.read(buf)) != -1) {  
            fos.write(buf, 0, i);  
        }  
    }  
    catch (Exception e) {  
        e.printStackTrace();  
    } finally {  
        close(fis);  
        close(fos);  
    }  
     public static void copyfile(File fromFile, File toFile,Boolean rewrite ){  
          
        if(!fromFile.exists()){  
            return;  
        }  
          
        if(!fromFile.isFile()){  
            return;  
        }  
        if(!fromFile.canRead()){  
            return;  
        }  
        if(!toFile.getParentFile().exists()){  
            toFile.getParentFile().mkdirs();  
        }  
        if(toFile.exists() && rewrite){  
            toFile.delete();  
        }  
          
          
        try {  
            FileInputStream fosfrom = new FileInputStream(fromFile);  
            FileOutputStream fosto = new FileOutputStream(toFile);  
              
            byte[] bt = new byte[1024];  
            int c;  
            while((c=fosfrom.read(bt)) > 0){  
                fosto.write(bt,0,c);  
            }  
            //关闭输入、输出流  
            fosfrom.close();  
            fosto.close();  
              
              
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
          
    }  

 

 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();  
                }  
            }  

 2. BufferedOutputStream  快

private static void customBufferBufferedStreamCopy(File source, File target) {  
    InputStream fis = null;  
    OutputStream fos = null;  
    try {  
        fis = new BufferedInputStream(new FileInputStream(source));  
        fos = new BufferedOutputStream(new FileOutputStream(target));  
        byte[] buf = new byte[4096];  
        int i;  
        while ((i = fis.read(buf)) != -1) {  
            fos.write(buf, 0, i);  
        }  
    }  
    catch (Exception e) {  
        e.printStackTrace();  
    } finally {  
        close(fis);  
        close(fos);  
    }  
}  


FileChannel 方式(针对体积大的文件)而且FileChannel是多并发线程安全的。

 

1.private static void nioTransferCopy(File source, File target) {  
    FileChannel in = null;  
    FileChannel out = null;  
    FileInputStream inStream = null;  
    FileOutputStream outStream = null;  
    try {  
        inStream = new FileInputStream(source);  
        outStream = new FileOutputStream(target);  
        in = inStream.getChannel();  
        out = outStream.getChannel();  
        in.transferTo(0, in.size(), out);  //连接两个通道,并且从in通道读取,然后写入out通道
    } catch (IOException e) {  
        e.printStackTrace();  
    } finally {  
        close(inStream);  
        close(in);  
        close(outStream);  
        close(out);  
    }  
} 


2.private static void nioBufferCopy(File source, File target) {  
    FileChannel in = null;  
    FileChannel out = null;  
    FileInputStream inStream = null;  
    FileOutputStream outStream = null;  
    try {  
        inStream = new FileInputStream(source);  
        outStream = new FileOutputStream(target);  
        in = inStream.getChannel();  
        out = outStream.getChannel();  
	//类似使用了缓冲 ---- 么有直接连接通道写入的快
        ByteBuffer buffer = ByteBuffer.allocate(4096);  
        while (in.read(buffer) != -1) {  
            buffer.flip();  
            out.write(buffer);  
            buffer.clear();  
        }  
    } catch (IOException e) {  
        e.printStackTrace();  
    } finally {  
        close(inStream);  
        close(in);  
        close(outStream);  
        close(out);  
    }  
}  


  3. /  * 使用文件通道的方式复制文件 
     */  
    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();  
            }  
        }  
          
    }


FileWriter 非常快   (FileWriter默认写page cache里,所以快)

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值