wang123

          使用org.apache.commons.net.ftp包開發FTP客戶端,實現進度匯報,實現斷點續傳,中文支持

          利用org.apache.commons.net.ftp包實現一個簡單的ftp客戶端實用類。主要實現一下功能

          1.支持上傳下載。支持斷點續傳

          2.支持進度匯報

          3.支持對于中文目錄及中文文件創建的支持。

          import java.io.File;   
          import java.io.FileOutputStream;   
          import java.io.IOException;   
          import java.io.InputStream;   
          import java.io.OutputStream;   
          import java.io.PrintWriter;   
          import java.io.RandomAccessFile;   
            
          import open.mis.data.DownloadStatus;   
          import open.mis.data.UploadStatus;   
            
          import org.apache.commons.net.PrintCommandListener;   
          import org.apache.commons.net.ftp.FTP;   
          import org.apache.commons.net.ftp.FTPClient;   
          import org.apache.commons.net.ftp.FTPFile;   
          import org.apache.commons.net.ftp.FTPReply;   
            
          /**  
           * 支持斷點續傳的FTP實用類  
           * 
          @author BenZhou  http://www.bt285.cn
           * 
          @version 0.1 實現基本斷點上傳下載  
           * 
          @version 0.2 實現上傳下載進度匯報  
           * 
          @version 0.3 實現中文目錄創建及中文文件創建,添加對于中文的支持  
           
          */
            
          public class ContinueFTP {   
              
          public FTPClient ftpClient = new FTPClient();   
                 
              
          public ContinueFTP(){   
                  
          //設置將過程中使用到的命令輸出到控制臺   
                  this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));   
              }
             
                 
              
          /**  
               * 連接到FTP服務器  
               * 
          @param hostname 主機名  
               * 
          @param port 端口  
               * 
          @param username 用戶名  
               * 
          @param password 密碼  
               * 
          @return 是否連接成功  
               * 
          @throws IOException  
               
          */
            
              
          public boolean connect(String hostname,int port,String username,String password) throws IOException{   
                  ftpClient.connect(hostname, port);   
                  ftpClient.setControlEncoding(
          "GBK");   
                  
          if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){   
                      
          if(ftpClient.login(username, password)){   
                          
          return true;   
                      }
             
                  }
             
                  disconnect();   
                  
          return false;   
              }
             
                 
              
          /**  
               * 從FTP服務器上下載文件,支持斷點續傳,上傳百分比匯報  
               * 
          @param remote 遠程文件路徑  
               * 
          @param local 本地文件路徑  
               * 
          @return 上傳的狀態  
               * 
          @throws IOException  
               
          */
            
              
          public DownloadStatus download(String remote,String local) throws IOException{   
                  
          //設置被動模式   
                  ftpClient.enterLocalPassiveMode();   
                  
          //設置以二進制方式傳輸   
                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);   
                  DownloadStatus result;   
                     
                  
          //檢查遠程文件是否存在   
                  FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));   
                  
          if(files.length != 1){   
                      System.out.println(
          "遠程文件不存在");   
                      
          return DownloadStatus.Remote_File_Noexist;   
                  }
             
                     
                  
          long lRemoteSize = files[0].getSize();   
                  File f 
          = new File(local);   
                  
          //本地存在文件,進行斷點下載   
                  if(f.exists()){   
                      
          long localSize = f.length();   
                      
          //判斷本地文件大小是否大于遠程文件大小   
                      if(localSize >= lRemoteSize){   
                          System.out.println(
          "本地文件大于遠程文件,下載中止");   
                          
          return DownloadStatus.Local_Bigger_Remote;   
                      }
             
                         
                      
          //進行斷點續傳,并記錄狀態   
                      FileOutputStream out = new FileOutputStream(f,true);   
                      ftpClient.setRestartOffset(localSize);   
                      InputStream in 
          = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));   
                      
          byte[] bytes = new byte[1024];   
                      
          long step = lRemoteSize /100;   
                      
          long process=localSize /step;   
                      
          int c;   
                      
          while((c = in.read(bytes))!= -1){   
                          out.write(bytes,
          0,c);   
                          localSize
          +=c;   
                          
          long nowProcess = localSize /step;   
                          
          if(nowProcess > process){   
                              process 
          = nowProcess;   
                              
          if(process % 10 == 0)   
                                  System.out.println(
          "下載進度:"+process);   
                              
          //TODO 更新文件下載進度,值存放在process變量中   
                          }
             
                      }
             
                      in.close();   
                      out.close();   
                      
          boolean isDo = ftpClient.completePendingCommand();   
                      
          if(isDo){   
                          result 
          = DownloadStatus.Download_From_Break_Success;   
                      }
          else {   
                          result 
          = DownloadStatus.Download_From_Break_Failed;   
                      }
             
                  }
          else {   
                      OutputStream out 
          = new FileOutputStream(f);   
                      InputStream in
          = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));   
                      
          byte[] bytes = new byte[1024];   
                      
          long step = lRemoteSize /100;   
                      
          long process=0;   
                      
          long localSize = 0L;   
                      
          int c;   
                      
          while((c = in.read(bytes))!= -1){   
                          out.write(bytes, 
          0, c);   
                          localSize
          +=c;   
                          
          long nowProcess = localSize /step;   
                          
          if(nowProcess > process){   
                              process 
          = nowProcess;   
                              
          if(process % 10 == 0)   
                                  System.out.println(
          "下載進度:"+process);   
                              
          //TODO 更新文件下載進度,值存放在process變量中   
                          }
             
                      }
             
                      in.close();   
                      out.close();   
                      
          boolean upNewStatus = ftpClient.completePendingCommand();   
                      
          if(upNewStatus){   
                          result 
          = DownloadStatus.Download_New_Success;   
                      }
          else {   
                          result 
          = DownloadStatus.Download_New_Failed;   
                      }
             
                  }
             
                  
          return result;   
              }
             
                 
              
          /**  
               * 上傳文件到FTP服務器,支持斷點續傳  
               * 
          @param local 本地文件名稱,絕對路徑  
               * 
          @param remote 遠程文件路徑,使用/home/directory1/subdirectory/file.ext或是 http://www.guihua.org /subdirectory/file.ext 按照Linux上的路徑指定方式,支持多級目錄嵌套,支持遞歸創建不存在的目錄結構  
               * 
          @return 上傳結果  
               * 
          @throws IOException  
               
          */
            
              
          public UploadStatus upload(String local,String remote) throws IOException{   
                  
          //設置PassiveMode傳輸   
                  ftpClient.enterLocalPassiveMode();   
                  
          //設置以二進制流的方式傳輸   
                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);   
                  ftpClient.setControlEncoding(
          "GBK");   
                  UploadStatus result;   
                  
          //對遠程目錄的處理   
                  String remoteFileName = remote;   
                  
          if(remote.contains("/")){   
                      remoteFileName 
          = remote.substring(remote.lastIndexOf("/")+1);   
                      
          //創建服務器遠程目錄結構,創建失敗直接返回   
                      if(CreateDirecroty(remote, ftpClient)==UploadStatus.Create_Directory_Fail){   
                          
          return UploadStatus.Create_Directory_Fail;   
                      }
             
                  }
             
                     
                  
          //檢查遠程是否存在文件   
                  FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1"));   
                  
          if(files.length == 1){   
                      
          long remoteSize = files[0].getSize();   
                      File f 
          = new File(local);   
                      
          long localSize = f.length();   
                      
          if(remoteSize==localSize){   
                          
          return UploadStatus.File_Exits;   
                      }
          else if(remoteSize > localSize){   
                          
          return UploadStatus.Remote_Bigger_Local;   
                      }
             
                         
                      
          //嘗試移動文件內讀取指針,實現斷點續傳   
                      result = uploadFile(remoteFileName, f, ftpClient, remoteSize);   
                         
                      
          //如果斷點續傳沒有成功,則刪除服務器上文件,重新上傳   
                      if(result == UploadStatus.Upload_From_Break_Failed){   
                          
          if(!ftpClient.deleteFile(remoteFileName)){   
                              
          return UploadStatus.Delete_Remote_Faild;   
                          }
             
                          result 
          = uploadFile(remoteFileName, f, ftpClient, 0);   
                      }
             
                  }
          else {   
                      result 
          = uploadFile(remoteFileName, new File(local), ftpClient, 0);   
                  }
             
                  
          return result;   
              }
             
              
          /**  
               * 斷開與遠程服務器的連接  
               * 
          @throws IOException  
               
          */
            
              
          public void disconnect() throws IOException{   
                  
          if(ftpClient.isConnected()){   
                      ftpClient.disconnect();   
                  }
             
              }
             
                 
              
          /**  
               * 遞歸創建遠程服務器目錄  
               * 
          @param remote 遠程服務器文件絕對路徑  
               * 
          @param ftpClient FTPClient對象  
               * 
          @return 目錄創建是否成功  
               * 
          @throws IOException  
               
          */
            
              
          public UploadStatus CreateDirecroty(String remote,FTPClient ftpClient) throws IOException{   
                  UploadStatus status 
          = UploadStatus.Create_Directory_Success;   
                  String directory 
          = remote.substring(0,remote.lastIndexOf("/")+1);   
                  
          if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"),"iso-8859-1"))){   
                      
          //如果遠程目錄不存在,則遞歸創建遠程服務器目錄   
                      int start=0;   
                      
          int end = 0;   
                      
          if(directory.startsWith("/")){   
                          start 
          = 1;   
                      }
          else{   
                          start 
          = 0;   
                      }
             
                      end 
          = directory.indexOf("/",start);   
                      
          while(true){   
                          String subDirectory 
          = new String(remote.substring(start,end).getBytes("GBK"),"iso-8859-1");   
                          
          if(!ftpClient.changeWorkingDirectory(subDirectory)){   
                              
          if(ftpClient.makeDirectory(subDirectory)){   
                                  ftpClient.changeWorkingDirectory(subDirectory);   
                              }
          else {   
                                  System.out.println(
          "創建目錄失敗");   
                                  
          return UploadStatus.Create_Directory_Fail;   
                              }
             
                          }
             
                             
                          start 
          = end + 1;   
                          end 
          = directory.indexOf("/",start);   
                             
                          
          //檢查所有目錄是否創建完畢   
                          if(end <= start){   
                              
          break;   
                          }
             
                      }
             
                  }
             
                  
          return status;   
              }
             
                 
              
          /**  
               * 上傳文件到服務器,新上傳和斷點續傳  
               * 
          @param remoteFile 遠程文件名,在上傳之前已經將服務器工作目錄做了改變  
               * 
          @param localFile 本地文件File句柄,絕對路徑  
               * 
          @param processStep 需要顯示的處理進度步進值  
               * 
          @param ftpClient FTPClient引用  
               * 
          @return  
               * 
          @throws IOException  
               
          */
            
              
          public UploadStatus uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{   
                  UploadStatus status;   
                  
          //顯示進度的上傳   
                  long step = localFile.length() / 100;   
                  
          long process = 0;   
                  
          long localreadbytes = 0L;   
                  RandomAccessFile raf 
          = new RandomAccessFile(localFile,"r");   
                  OutputStream out 
          = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));   
                  
          //斷點續傳   
                  if(remoteSize>0){   
                      ftpClient.setRestartOffset(remoteSize);   
                      process 
          = remoteSize /step;   
                      raf.seek(remoteSize);   
                      localreadbytes 
          = remoteSize;   
                  }
             
                  
          byte[] bytes = new byte[1024];   
                  
          int c;   
                  
          while((c = raf.read(bytes))!= -1){   
                      out.write(bytes,
          0,c);   
                      localreadbytes
          +=c;   
                      
          if(localreadbytes / step != process){   
                          process 
          = localreadbytes / step;   
                          System.out.println(
          "上傳進度:" + process);   
                          
          //TODO 匯報上傳狀態   
                      }
             
                  }
             
                  out.flush();   
                  raf.close();   
                  out.close();   
                  
          boolean result =ftpClient.completePendingCommand();   
                  
          if(remoteSize > 0){   
                      status 
          = result?UploadStatus.Upload_From_Break_Success:UploadStatus.Upload_From_Break_Failed;   
                  }
          else {   
                      status 
          = result?UploadStatus.Upload_New_File_Success:UploadStatus.Upload_New_File_Failed;   
                  }
             
                  
          return status;   
              }
             
                 
              
          public static void main(String[] args) {   
                  ContinueFTP myFtp 
          = new ContinueFTP();   
                  
          try {   
                      myFtp.connect(
          "192.168.21.181"21"nid""123");   
          //          myFtp.ftpClient.makeDirectory(new String("電視劇".getBytes("GBK"),"iso-8859-1"));   
          //          myFtp.ftpClient.changeWorkingDirectory(new String("電視劇".getBytes("GBK"),"iso-8859-1"));   
          //          myFtp.ftpClient.makeDirectory(new String("走西口".getBytes("GBK"),"iso-8859-1"));   
          //          System.out.println(myFtp.upload("http://www.5a520.cn /yw.flv", "/yw.flv",5));   
          //          System.out.println(myFtp.upload("http://www.5a520.cn /走西口24.mp4","/央視走西口/新浪網/走西口24.mp4"));   
                      System.out.println(myFtp.download("/央視走西口/新浪網/走西口24.mp4""E:\\走西口242.mp4"));   
                      myFtp.disconnect();   
                  }
           catch (IOException e) {   
                      System.out.println(
          "連接FTP出錯:"+e.getMessage());   
                  }
             
              }
             
          }
            

          posted on 2009-03-10 16:34 閱讀(6066) 評論(0)  編輯  收藏

          <2009年3月>
          22232425262728
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(3)

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 交口县| 闽清县| 长寿区| 鄱阳县| 即墨市| 宁蒗| 峨边| 临西县| 紫云| 济南市| 濮阳县| 连山| 阿尔山市| 华安县| 台安县| 甘南县| 抚远县| 新宁县| 泗阳县| 巴彦县| 杭锦旗| 威信县| 公安县| 讷河市| 思茅市| 惠安县| 综艺| 菏泽市| 美姑县| 游戏| 南康市| 阳春市| 英吉沙县| 泗水县| 莫力| 漠河县| 津市市| 武功县| 汾阳市| 广平县| 兰西县|