一個文件復制的兩種方法的實現

          Posted on 2007-05-25 16:17 Computerboy 閱讀(2110) 評論(4)  編輯  收藏 所屬分類: 編程技術

          一個文件的復制我們大概的思維是通過流來操作,不錯。
          本文也是這樣操作的。
          至于第一種方法是我們一般的操作方式,而第二種方法其實也是一個方式,我們不妨研究一下。
          閑話少說。看程序。

          這個程序我寫的是兩個方法,支持從命令行操作。
          例一:
          package org.stonecn.kernel;
          import java.io.*;
          public class FileCopy {
           /**
            * 測試程序
            */
           public static void main(String[] args){
            if(args.length!=2)
             System.err.println("Usage: java FileCopy<source><destination>");
            else{
             try{
              copy(args[0],args[1]);
             }
             catch(IOException e){
              System.err.println(e.getMessage());
             }
            }
           }
           public static void copy(String from_name,String to_name)throws IOException{
            File from_file=new File(from_name);
            File to_file=new File(to_name);
            if(!from_file.exists())
             abort("no such source file:"+from_name);
            if(!from_file.isFile())
             abort("can't copy directory:"+from_name);
            if(!from_file.canRead())
             abort("source file is unreadable:"+from_name);
            /**
             * 如果目標是一個目錄,則使用源文件名作為目標文件名
             */
            if(to_file.isDirectory())
             to_file=new File(to_file,from_file.getName());
            /**
             * 如果目標文件存在,則確保它是可寫的,并且在覆蓋之前先詢問
             * 如果目標文件不存在,則確保存在目錄,而且是可寫的。
             */
                           // 此處支持命令行,如果不用可以注視掉。    sart  
            if(to_file.exists()){
             abort("destination file is unwriteable:"+to_name);
             //詢問是否覆蓋
             System.out.print("Overwrite existing file:"+to_file.getName()+"?(Y/N):");
             //得到用戶響應
             System.out.flush();
             BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
             String response=in.readLine();
             //檢查響應,如果不是yes(未做確認),則終止復制
             if(!response.equals("Y") && !response.equals("y"))
              abort("existing file was not overwritten.");
            }
            else{
             /**如果文件不存在,檢查是否存在目錄且是否可寫
              * 如果getParent()返回null,則目錄就是當前dir,
              * 因此查找user.dir系統特性,以得出它是什么
              */
             String parent=to_file.getParent();  //目標目錄
             if(parent == null)
              parent=System.getProperty("user.dir");
             File dir=new File(parent);
             if(!dir.exists())
              abort("destination directory doesn't exist:"+parent);
             if(dir.isFile())
              abort("destination is not a directory:"+parent);
             if(!dir.canWrite())
              abort("destination directory is unwriteable:"+parent);
            }
                            //到此結束      end 
            /**
             * 如果走到這了,則一切正常。
             * 因此可以復制文件,一次復制一個字節緩沖區
             */
            FileInputStream from=null;   //從源讀取的流
            FileOutputStream to=null;    //寫至目標的流
            try{
             from=new FileInputStream(from_file); //創建輸入流
             to=new FileOutputStream(to_file);    //創建輸出流
             byte[] buffer=new byte[4096];
             int bytes_read;
             /**
              * 將一塊字節讀入緩沖區,然后將其寫出
              * 如果循環,知道達到文件結束(read()返回-1)
              * 注意,在此while循環中結合了賦值和比較
              */
             while((bytes_read=from.read(buffer))!=-1)  //讀,直到EOF
              to.write(buffer,0,bytes_read);         //寫
            }
            finally{
             if(from!=null)
              try{
               from.close();
              }
             catch(IOException e){
              ;
             }
             if(to!=null)
              try{
               to.close();
              }
             catch(IOException e){;}
            }
           }
           /**
            * 這是拋出異常的一個便利方法
            */
           private static void abort(String msg)throws IOException{
            throw new IOException("FileCopy:"+msg);
           }

          }


          這個程序的好處是一個安全的。因為有一個靜態的copy方法。其他程序也可以使用此方法來復制文件

           

          我們來看第二個例子

          例二:
          package org.stonecn.kernel;
          import java.io.*;
          import java.nio.channels.*;

           public class FileCopy2{
            public static void main(String[] args){
             FileInputStream fin=null;       //兩個文件的流
             FileOutputStream fout=null;     //這些流要在finally塊中關閉
             try{
              //打開輸入文件的一個流,并從中得到一個通道
              fin=new FileInputStream(args[0]);
              FileChannel in=fin.getChannel();
              
              //下面得到輸出通道
              WritableByteChannel out;
              //如果有第二個文件名
              if(args.length>1){
               fout=new FileOutputStream(args[1]);
               out=fout.getChannel();
              }
              else{
               //沒有目標文件名
               out=Channels.newChannel(System.out);   //包裝stdout流
              }
              //查詢輸入文件的大小
              long numbytes=in.size();
              /**
               *采用批量傳輸的方式將所有字節從一個通道傳輸到另一個通道
               *這是fileChannel通道的一個特殊特性
               *參見FileChannel.transferForm()
               */
               in.transferTo(0,numbytes,out);
              
             }
             catch(IOException e){
              System.out.println(e);
             }
             finally{
              try{
               if(fin!=null)  fin.close();
               if(fout!=null)  fout.close();
              }
              catch(IOException e){
              }
             }
             
            }
           }


          而這個程序將其第一個參數中指定的文件復制到第二個參數所指定的文件中。
          如果沒有第二個參數則復制到標準輸出。

          同樣的方式,兩種實現,這就是我們所說的結果一樣,而過程也是千變萬化。
          例二所涉及的包是我以前所沒有接觸到的。
          歡迎朋友們來指正。

           

           

           

           

          Feedback

          # re: 一個文件復制的兩種方法的實現  回復  更多評論   

          2007-05-25 17:36 by dennis
          static跟安全有什么關系?呵呵

          # re: 一個文件復制的兩種方法的實現  回復  更多評論   

          2007-05-25 17:54 by Computerboy
          呵呵,樓上的朋友說的好。
          呵呵,
          我例二的例子是展示了一個特殊的批量傳輸方法:這是FileChannel 類所有特有的:transferTo()方法將文件的全部內容復制到指定的通道,而無需顯示的分配任何ByteBuffer對象,這個方法對于web服務器和其他的傳輸文件內容的應用都特別有用。但是它互有了例一的FileCopy的安全特性,而且可以重寫現有文件,因此我稱為安全的。這是相對的。呵呵。

          # re: 一個文件復制的兩種方法的實現  回復  更多評論   

          2007-05-25 18:17 by BeanSoft
          不錯, Java NIO 性能很好的, 可惜都沒時間來看了.

          # 似的  回復  更多評論   

          2007-09-21 14:32 by 似的但是
          re: 一個文件復制的兩種方法的實現

          posts - 40, comments - 39, trackbacks - 0, articles - 0

          Copyright © Computerboy

          主站蜘蛛池模板: 林芝县| 临邑县| 利津县| 酒泉市| 新营市| 岗巴县| 芦溪县| 千阳县| 东平县| 炉霍县| 阜新市| 无为县| 和平县| 鹤山市| 历史| 大荔县| 浦城县| 嘉荫县| 静安区| 秦皇岛市| 白山市| 丰原市| 丽江市| 新野县| 荣成市| 靖宇县| 彩票| 永胜县| 兰溪市| 于田县| 无棣县| 陇南市| 金山区| 澄江县| 武强县| 嘉鱼县| 砚山县| 马鞍山市| 鹤山市| 日喀则市| 邢台市|