ftp断点续传


1      断点续传

1.1    简介

断点续传指得是在上传或是下载时,由于网络或是其他原因中断了,下次可以从中断的的地方继续上传或是下载,不需要重头来过,用途可以提高效率。

1.2    原理

原理其实很简单,比起普通的上传或是下载,你多了一步设置上传和下载的开始位置。

如果是上传,你需要向服务器发送请求,知道在服务器上的文件的大小,然后以这个大小为开始位置上传。反之,下载就是你告诉服务器你本地文件的大小,服务器会根据这个大小设置开始位置下载。

1.3    实例

文件服务端:Apache Ftp Server(任意ftp服务器都可以)

客户端:commons-net.jar中的FTPClient

 

package com.rj.eden.attachment.test;

 

import java.io.File;

import java.io.FileOutputStream;

package com.rj.eden.attachment.test;

 

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 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;

 

import com.rj.eden.attachment.common.CommonContext;

import com.rj.eden.attachment.common.DownloadStatus;

import com.rj.eden.attachment.common.UploadStatus;

 

/**

 * 功能说明:  <br>

 * 系统版本: v1.0 <br>

 * 开发人员: chenglibin@rongji.com<br>

 * 开发时间: 2013-9-30<br>

 * 审核人员:  <br>

 * 相关文档:  <br>

 * 修改记录:  <br>

 * 修改日期 修改人员 修改说明  <br>

 * ======== ================================================== <br>

 *

 */

public class TestFTP {

 

public FTPClient ftpClient = new FTPClient();

 

public static String FTP_ENCODE="UTF-8";

      

       public TestFTP(){

       }

       /**

        * 连接到FTP服务器

        * @param hostname 主机名

        * @param port 端口

        * @param username 用户名

        * @param password 密码

        * @return 是否连接成功

        * @throws IOException

        */

       public booleanconnect(String hostname,int port,String username,String password) throwsIOException{

              ftpClient.setControlEncoding(FTP_ENCODE);

              ftpClient.connect(hostname,port);  

              if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){

                     if(ftpClient.login(username,password)){

                            returntrue;

                     }

              }

              disconnect();

              returnfalse;

       }

      

       /**

        * 断开与远程服务器的连接

        * @throws IOException

        */

       public voiddisconnect() throws IOException{

              if(ftpClient.isConnected()){

                     ftpClient.disconnect();

              }

       }

      

       /**

        * 上传文件到FTP服务器,支持断点续传

        * @param local 本地文件名称,绝对路径

        * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构

        * @return 上传结果

        * @throws IOException

        */

       public booleanupload(String local,String remote) throws IOException{

              //设置PassiveMode传输

              ftpClient.enterLocalPassiveMode();

              //设置以二进制流的方式传输

              ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

             

              //对远程目录的处理

              StringremoteFileName = remote;

              if(remote.contains("/")){

                     remoteFileName= remote.substring(remote.lastIndexOf("/")+1);

                     //创建服务器远程目录结构,失败报异常

                     CreateDirecroty(remote);                  

              }

              //检查远程是否存在文件

              FTPFile[]files = ftpClient.listFiles(remoteFileName);

              File f =new File(local);

              RandomAccessFileraf = new RandomAccessFile(f,"r");

              OutputStreamout = ftpClient.appendFileStream(remoteFileName);

              longlocalSize = f.length();

              if(files.length== 1){

                     //服务器文件的大小

                     longremoteSize = files[0].getSize();

                     if(remoteSize<localSize){

                            //设置上传的开始位置

                            raf.seek(remoteSize);

                     }else{

                            ftpClient.deleteFile(remoteFileName);

                     }     

              }

             

              byte[]bytes = new byte[1024*1024];

              int c;

              while((c =raf.read(bytes))!= -1){

                     out.write(bytes,0,c);

              }

              out.flush();

              raf.close();

              out.close();

              returnftpClient.completePendingCommand();

             

       }

      

       /**

        * 递归创建远程服务器目录

        * @param remote 远程服务器文件绝对路径

        * @throws IOException

        */

       public voidCreateDirecroty(String remote) throws IOException{

              Stringdirectory = remote.substring(0,remote.lastIndexOf("/")+1);

              if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){

                     //如果远程目录不存在,则递归创建远程服务器目录

                     intstart=0;

                     intend = 0;

                     if(directory.startsWith("/")){

                            start = 1;

                     }else{

                            start= 0;

                     }

                     end= directory.indexOf("/",start);

                     while(true){

                            StringsubDirectory = remote.substring(start,end);

                            if(!ftpClient.changeWorkingDirectory(subDirectory)){

                                   if(ftpClient.makeDirectory(subDirectory)){

                                          ftpClient.changeWorkingDirectory(subDirectory);

                                   }else{

                                       throw new IOException("创建文件夹"+subDirectory+"失败");

                                   }

                            }

                           

                            start= end + 1;

                            end= directory.indexOf("/",start);

                           

                            //检查所有目录是否创建完毕

                            if(end<= start){

                                   break;

                            }

                     }

              }

       }

      

       /**

        * 从FTP服务器上下载文件,支持断点续传,上传百分比汇报

        * @param remote 远程文件路径

        * @param local 本地文件路径

        * @return 上传的状态

        * @throws IOException

        */

       public booleandownload(String remote,String local) throws IOException{

              //设置被动模式

              ftpClient.enterLocalPassiveMode();

              //设置以二进制方式传输

              ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

 

              File f =new File(local);

              FileOutputStreamout = new FileOutputStream(f,true);

             

              //检查远程文件是否存在

              FTPFile[]files = ftpClient.listFiles(remote);

              if(files.length==0){

                     thrownew IOException("服务器不存在"+remote);

              }

              //本地存在文件,进行断点下载

              if(f.exists()){

                     longlocalSize = f.length();

                     longRemoteSize = files[0].getSize();

                     if(localSize<RemoteSize){

                            //设置下载的开始位置

                            ftpClient.setRestartOffset(localSize);     

                     }

                    

              }

              InputStreamin = ftpClient.retrieveFileStream(remote);

              byte[]bytes = new byte[1024*1024];

              int c;

              while((c =in.read(bytes))!= -1){

                     out.write(bytes,0,c);

              }

              in.close();

              out.close();

              returnftpClient.completePendingCommand();

       }

       public staticvoid main(String[] args) {

              TestFTPmyFtp = new TestFTP();

              try {

                     myFtp.connect("127.0.0.1",2121,"admin","admin");

                     System.out.println(myFtp.upload("D:\\upload1\\合成A.jpg","/我们/合成A.jpg"));

                     //System.out.println(myFtp.download("/zhenchen.jpg","D:\\upload1\\我们\\cc1.txt"));

                     myFtp.disconnect();

              } catch(IOException e) {

                     System.out.println("连接FTP出错:"+e.getMessage());

              }

       }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT是一种跨平台的C++库,可以方便地进行ftp断点续传FTP断点续传是指在文件传输过程中,当传输中断后,可以在下次传输时从中断的位置继续传输,而不需要重新传输整个文件。 在QT中实现ftp断点续传的关键是利用Qt的QNetworkAccessManager类和QNetworkReply类。首先,我们需要使用QNetworkAccessManager类建立与FTP服务器的连接,并发送GET命令获取文件。在QNetworkReply的finished()信号槽中可以检查文件的是否已下载完整,如果未完整下载,则可以通过设置Range请求头部来实现断点续传。这里的Range请求头部指定了从断点位置开始的字节数到文件末尾的字节数。 接下来,我们需要获取断点位置,可以通过QFile的size()方法获取已经下载的文件大小,然后将断点位置传递给FTP服务器。在Qt的QUrl的setEncodedQueryItem()方法中设置文件下载的起始位置。 等到下载完整个文件后,我们可以使用QFile类的seek()方法将文件指针移动到断点位置处,然后重新发起GET请求,继续从断点位置下载文件剩余部分。在QNetworkReply的finished()信号槽中,再次检查文件是否已下载完整,如果未完整下载,则继续进行断点续传。 通过以上步骤,我们就可以在QT中实现ftp断点续传功能。在实际应用中,我们还需要处理网络连接的中断、服务器断开连接等情况,以确保断点续传的可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值