使用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(remoteFile

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值