Java_IO_兩種文件複製方式

一:緩衝輸入輸出流(InputStream、OutputStream)
[java] view plain copy

<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

<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

<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 - 目標通道   
返回:  
實際已傳輸的字節數,可能爲零  
發佈了53 篇原創文章 · 獲贊 39 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章