天天看點

FTP 斷點續傳工具

**

* 類描述: 檔案斷點續傳工具類

* @author:趙博

* @since:2017-6-14 下午13:41

* @update:[變更日期YYYY-MM-DD][更改人姓名][變更描述]

*

*

*/

public class ContinueFTP2 {

public FTPClient ftpClient = new FTPClient(); 
 private String ftpURL,username,pwd,ftpport,file1,file2; 


 /******
  * 
  * @param _ftpURL     檔案伺服器長傳位址
  * @param _username   使用者名
  * @param _pwd        密碼
  * @param _ftpport    端口
  * @param _file1            要傳輸的檔案
  * @param _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; 
     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;   
    }  


    /** *//**  
     * 斷開與遠端伺服器的連接配接  
     * @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 void downloadFile(String remote,String local){

        try{

            FTPFile[] filelist=ftpClient.listFiles(remote);
            FTPFile ftpFile = null;
            String category = null;
            int length = filelist.length;
            for (int i = 0; i < length; i++) {
                ftpFile = filelist[i];
                category = ftpFile.getName();
                if(ftpFile.isFile()){
                    download(remote+category, local+category);
                }else{

                    String wjj=local+category;
                    File file=new File(wjj);
                    if(file.exists()){
                        downloadFile(remote+category+"//", local+category+"\\");
                    }else{
                        if(file.mkdir()){
                            downloadFile(remote+category+"//", local+category+"\\");
                        }
                    }


                }


            }



        }catch(Exception e){
            System.out.println(e.getMessage());
        }

    }


    /** *//**  
     * 從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;   
    } 

    public void moveFTPFile(FTPClient ftpClient, String from, String to){

        boolean result=true;

        try {

            FTPFile[] filelist=ftpClient.listFiles(from);
            FTPFile ftpFile = null;
            String category = null;
            int length = filelist.length;
            for (int i = 0; i < length; i++) {
                ftpFile = filelist[i];
                category = ftpFile.getName();
                if (ftpFile.isFile()) {

                    ftpClient.rename(from+category, to+category);
                }else{

                    ftpClient.rename(from+category, to+category);

                    //moveFTPFile(ftpClient,from+category+"//",to+"//");
                }

            }



        } catch (IOException e) {
            // TODO 自動生成的 catch 塊
            e.printStackTrace();
        }


    }



    public  boolean copyFTPFile(FTPClient ftpClient, String from, String to){

        boolean copyFalg = false;
        FTPFile[] filelist;
        try {
            // 枚舉目前from目錄所有檔案+子目錄
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            filelist = ftpClient.listFiles(from);
            int length = filelist.length;
            FTPFile ftpFile = null;
            String category = null;
            InputStream inputStream = null;
            for (int i = 0; i < length; i++) {
                ftpFile = filelist[i];
                category = ftpFile.getName();
                if (ftpFile.isFile()) {

                    ftpClient.setBufferSize(1024); 
                      ByteArrayOutputStream fos=new ByteArrayOutputStream();
                      ftpClient.retrieveFile(from, fos);
                      ByteArrayInputStream in=new ByteArrayInputStream(fos.toByteArray());
                      ftpClient.storeFile(to, in);
                      fos.close();
                      in.close();

                } else if (ftpFile.isDirectory()) {
                    // 如果是目錄則先建立該目錄
                   // copyFalg = ftpClient.makeDirectory(to);
                    // 再進入子目錄進行遞歸複制
                    //copyDirectory(ftpClient, from , to);
                }
            }
        } catch (IOException e) {
           // logger.error("FtpClientUtil.copyDirectory failed. caused by " + e.getMessage(), e);
            copyFalg = false;
        }
        return copyFalg;


    }

    public boolean delete(FTPClient ftpClient,String deltefile){

        try {
            ftpClient.deleteFile(deltefile);
        } catch (IOException e) {
            // TODO 自動生成的 catch 塊
            e.printStackTrace();
        }

        return true;
    }


    public static void main(String args[]){


        try {
            ContinueFTP2 ftp=new ContinueFTP2("192.168.7.24", "username", "password", "21", null, null);
            boolean isconnect=ftp.connect("192.168.7.24", 21, "username", "password");
            String from="//CloudStation//web-tps-file//pinncal//pending//";
            String to="//CloudStation//web-tps-file//pinncal//alreadyDeal//";
            String resulttpssb="//CloudStation//web-tps-file//pinncal//result//deal-fail//";
            String resulttpscg="//CloudStation//web-tps-file//pinncal//result//deal-succeed//";
            String tbcg="E:\\資訊中心研發部\\開發項目文檔\\架構設計文檔\\網頁自動計劃\\雲端TPS檔案區域\\result\\deal-succeed\\";
            String tbsb="E:\\資訊中心研發部\\開發項目文檔\\架構設計文檔\\網頁自動計劃\\雲端TPS檔案區域\\result\\deal-fail\\";
            if(isconnect){
                long remotesize=1024L;
                ftp.downloadFile(resulttpssb,tbsb);
                //ftp.moveFTPFile(ftp.ftpClient, from, from, to);
                ftp.downloadFile(resulttpscg,tbcg);

                //ftp.moveFTPFile(ftp.ftpClient, from, to);
                //ftp.copyFTPFile(ftp.ftpClient, from,to);
            //  ftp.delete(ftp.ftpClient, from);
                //ftp.uploadFile("//CloudStation//web-tps-file//pinncal//1.xlsx", new File("C:\\Users\\Allcure\\Downloads\\1.xlsx"), ftp.ftpClient, remotesize);
            }



        } catch (IOException e) {
            // TODO 自動生成的 catch 塊
            e.printStackTrace();
        }


    }
           
ftp