`
高级java工程师
  • 浏览: 412362 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java实现FTP多线程断点续传,上传下载!

阅读更多
package com.ftp;

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 org.junit.Test;
/** *//** 
* 支持断点续传的FTP实用类 
* @version 0.1 实现基本断点上传下载 
* @version 0.2 实现上传下载进度汇报 
* @version 0.3 实现中文目录创建及中文文件创建,添加对于中文的支持 
*/ 
public class ContinueFTP2  implements Runnable{  

//枚举类UploadStatus代码

public enum UploadStatus {
Create_Directory_Fail,   //远程服务器相应目录创建失败
Create_Directory_Success, //远程服务器闯将目录成功
Upload_New_File_Success, //上传新文件成功
Upload_New_File_Failed,   //上传新文件失败
File_Exits,      //文件已经存在
Remote_Bigger_Local,   //远程文件大于本地文件
Upload_From_Break_Success, //断点续传成功
Upload_From_Break_Failed, //断点续传失败
Delete_Remote_Faild;   //删除远程文件失败
}

//枚举类DownloadStatus代码
public enum DownloadStatus {
Remote_File_Noexist, //远程文件不存在
Local_Bigger_Remote, //本地文件大于远程文件
Download_From_Break_Success, //断点下载文件成功
Download_From_Break_Failed,   //断点下载文件失败
Download_New_Success,    //全新下载文件成功
Download_New_Failed;    //全新下载文件失败
}

    public FTPClient ftpClient = new FTPClient();  
    private String ftpURL,username,pwd,ftpport,file1,file2;   
    public ContinueFTP2(String _ftpURL,String _username,String _pwd,String _ftpport,String _file1,String _file2 ){  
        //设置将过程中使用到的命令输出到控制台  
     ftpURL = _ftpURL;
     username = _username;
     pwd = _pwd;
     ftpport = _ftpport;
     file1 = _file1;
     file2 = _file2;
        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;  
    }  
      
   
    @Test
  
public void run() {
  // TODO Auto-generated method stub
   
         try {  
          this.connect(ftpURL, new java.lang.Integer(ftpport), username, pwd);
//           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"));
         
           this.download(file1, file2);
         //  System.out.println(myFtp.upload("c:\\a.iso", "/a.iso"));
             this.disconnect();  
         } catch (IOException e) {  
             System.out.println("连接FTP出错:"+e.getMessage());  
         }  
}  

分享到:
评论

相关推荐

    java实现FTP多线程断点续传

    ### Java实现FTP多线程断点续传:深入解析与技术要点 在现代软件开发中,数据传输是一项基本且关键的任务,特别是在处理大文件时,断点续传功能显得尤为重要。断点续传允许在网络连接中断后恢复传输,避免了重新...

    自己收集的多个Java FTP断点续传的例子源码

    java实现FTP多线程断点续传,上传下载! - java学习与交流 - j2ee学习网 - j2ee学习网 (2012年5月21日) 用 Java 实现断点续传 (HTTP) (2012年5月21日) Java写的支持断点续传的FTP--crybaby的博客 (2012年5月21日) ...

    java ftp 多线程 断点续传等知识

    而"多线程"和"断点"这两个文件名可能是指相关示例代码或文档,可以进一步帮助你理解和实践Java FTP的多线程下载和断点续传。 在实际应用中,还需要考虑其他因素,如错误处理、网络状况的监控、文件完整性检查等。...

    java FTP多线程 批量 断点续传

    Java FTP多线程批量断点续传是一种在Java编程中实现高效、稳定文件传输的方法,尤其适用于大文件的上传和下载。在这个过程中,我们利用FTP(File Transfer Protocol)协议,结合多线程技术和断点续传功能,可以显著...

    Http/FTP多线程断点续传下载组件

    点量Http、FTP多线程断点续传下载组件(下载DLL)的开发目的是让用户可以无需关心Http/FTP协议的具体细节,只需要几十行甚至几行代码,便可以实现一个功能完善的Http/FTP下载软件。点量Http/FTP下载组件(DLL)支持...

    点量Http/FTP多线程断点续传下载组件DLL

    点量Http、FTP多线程断点续传下载组件(下载DLL)的开发目的是让用户可以无需关心Http/FTP协议的具体细节,只需要几十行甚至几行代码,便可以实现一个功能完善的Http/FTP下载软件。点量Http/FTP下载组件(DLL)支持...

    ftp协议实现多线程断点续传

    在编程中实现FTP多线程断点续传,可以利用各种FTP库,例如Python的`ftplib`、Java的`java.net.Socket`与`java.net.URL`、C#的`System.Net.FtpWebRequest`等。这些库提供了处理FTP连接、命令和数据传输的接口,简化了...

    java大文件分块上传断点续传demo

    本示例"java大文件分块上传断点续传demo"提供了一个完整的解决方案,它允许用户将大文件分块上传,并在上传过程中支持断点续传。 首先,理解"分块上传"的概念。分块上传是将一个大文件分割成多个小块,然后逐个上传...

    多线程实现ftp断点续传

    以下是一个简化的多线程FTP断点续传实现步骤: 1. **初始化连接**:创建一个FTP客户端线程,负责与服务器建立连接,登录,并切换到目标目录。 2. **检查文件状态**:客户端线程询问服务器目标文件是否存在,如果...

    商业编程-源码-ftp协议实现多线程断点续传.zip

    实现FTP多线程断点续传通常涉及创建FTP客户端类,处理控制连接和数据连接,管理线程,以及实现断点续传逻辑。开发者可能需要使用如Python的`ftplib`库,Java的`java.net.Socket`和`java.net.FTPSClient`,或C#的`...

    ftp.rar_FTP 断点续传_Java FTP上传_ftp 断点_ftp断点续传Java_java ftp

    在这个Java FTP项目中,我们关注的是如何实现FTP的断点续传功能,以及如何利用Java进行多线程FTP上传。 断点续传是FTP的一个重要特性,它允许在文件传输中断后从上次停止的地方继续,而不是重新开始整个文件的传输...

    java FTP多线程、批量、断点续传实例

    在FTP多线程传输中,每个线程负责一个文件的上传或下载,这样可以同时处理多个文件,提高整体传输速度。在`ContinueFTP.java`中,可能会定义一个类来封装FTP操作,并通过创建多个线程实例,分别对不同的文件进行操作...

    Android FTP 多线程断点续传下载\上传的实例

    **Android FTP多线程断点续传实现** 在Android中,我们可以利用Apache Commons Net库来实现FTP功能。首先,我们需要创建FTPClient对象并连接到FTP服务器,然后进行登录操作。登录成功后,要获取文件的大小和名称,...

    多线程断点续传

    多线程断点续传是一种高效且实用的文件下载技术,尤其在处理大文件或网络不稳定的情况下,能够显著提升用户体验。下面将详细解释这一技术的关键概念、实现原理以及相关知识点。 1. **多线程**:多线程是指程序中...

    socket做的支持多线程断点上传or断点续传

    以上就是使用Java Socket实现多线程断点上传或断点续传的关键知识点。实际开发中,可能还会涉及到其他技术,如FTP、HTTP/HTTPS协议、数据库操作等,但核心思路是利用Socket进行网络通信,通过多线程和断点续传技术...

    java实现FTP断点续传

    Java 实现 FTP 断点续传是一项常见的网络编程任务,主要应用于大文件传输,以提高文件上传或下载的效率和可靠性。FTP(File Transfer Protocol)是互联网上用于在不同计算机之间传输文件的标准协议。断点续传允许在...

    商业编程-源码-FTP、HTTP 多线程断点续传下载文件.zip

    这个压缩包"商业编程-源码-FTP、HTTP 多线程断点续传下载文件.zip"包含的源码着重展示了如何利用FTP(文件传输协议)和HTTP(超文本传输协议)实现多线程的断点续传下载功能,这在大型文件下载或网络环境不稳定的...

    多线程断点续传下载控件

    多线程断点续传下载控件是一种高效且灵活的软件组件,专为优化网络下载体验而设计。这种控件通常被集成到应用程序中,提供强大的下载管理功能,包括分块下载、断点续传、速度显示以及进度条更新等。下面我们将详细...

    支持多线程断点续传的文件传输(FTP)程序(含服务端和客户端、支持蓝牙(Bluetooth)传输).zip

    本文将深入探讨一个特定的文件传输解决方案:支持多线程断点续传的FTP程序,该程序同时包含服务端和客户端,并且具备蓝牙传输功能。这样的系统设计能够显著提高文件传输效率,尤其是在网络不稳定或大文件传输时,其...

    Android ftp断点续传Demo

    本项目“Android ftp断点续传Demo”旨在演示如何在Android应用中实现FTP客户端功能,支持断点续传,即在中断后能够从上次停止的地方继续传输文件,这对于大文件的传输尤其有用。以下将详细介绍该Demo涉及的关键知识...

Global site tag (gtag.js) - Google Analytics