簡體   English   中英

使用apache FTPClient從FTP服務器下載文件

[英]File Download from a FTP Server using apache FTPClient

我正在使用apache的FTPClient從FTP服務器下載文件。 我的情況是-FTP服務器可能會失去網絡連接,並且可能最多保持1天處於斷開連接狀態。 重新連接后,應從剩余位置開始下載文件。 我正在使用以下代碼連接到服務器,然后從服務器下載文件

public void retrieve(String server, int port, String username,
        String password, String remote, String local, int fileType,
        ProgressHandler progressHandler) throws Exception {     
    final FTPClient ftp = new FTPClient();
    Date date = new Date();
    long startTime_ms = date.getTime();
    if (progressHandler != null) {
        ftp.setCopyStreamListener(new FtpCopyStreamListener(progressHandler));
    }

    ftpConnect(server,ftp, port,startTime_ms);


    if(ftp.getReplyCode()==0 || !String.valueOf(ftp.getReplyCode()).startsWith("2")){
        cleanup(ftp, "Could not log into server: " + server, null);
        return;
    }

    boolean loggedIn = false;
    try {
        if (username == null || username.isEmpty()) {
            username = "anonymous";
            password = System.getProperty("user.name") + "@"
                    + InetAddress.getLocalHost().getHostName();
        }
        if (!ftp.login(username, password)) {
            ftp.logout();
            cleanup(ftp, "Could not log into server: " + server, null);
        }
        loggedIn = true;

        ftp.setFileType(fileType);
        ftp.enterLocalPassiveMode();
        OutputStream output = null;
        try {
            output = new FileOutputStream(local);
            LOGGER.info("About to download " + remote + " from " + server
                    + " on " + (port > 0 ? port : ftp.getDefaultPort())
                    + " to " + local);              
            ftp.setControlKeepAliveTimeout(300);
            boolean isFileDownloaded = false;
            try{
                isFileDownloaded = ftp.retrieveFile(remote, output);

            }
            catch(IOException ex){
                if(ftp.isConnected()){

                    try{
                        int retryCode = 0;
                        while (!String.valueOf(retryCode).startsWith("2") && (new Date().getTime() < (startTime_ms + TOTAL_DURATION_MSECS))){
                            try{

                                 retryCode = ftp.retr(local);
                            }catch(Exception e1){
                                Thread.sleep(1000);
                                System.out.println("File not downloaded !! " + e1.toString());
                                ftpConnect(server, ftp, port, startTime_ms);
                            }

                        }
                    }catch(Exception e){
                        //ftp.getReplyCode()
                        //throw e;
                        //disconnect(ftp);
                        //ftpConnect(server, ftp, port, startTime_ms);

                        System.out.println("File not downloaded !! " + e.toString());
                    }                   
                }
            }
            if(isFileDownloaded){
                LOGGER.info("Finished downloading " + remote + " from "
                        + server + " on "
                        + (port > 0 ? port : ftp.getDefaultPort()) + " to "
                        + local);
            }
            else{
                System.out.println("File not downloaded !! ");
            }           

        }catch(IOException io){
            io.printStackTrace();

            throw io;
        }           
        finally {
            if (output != null) {
                try {
                    output.close();
                } catch (IOException f) {
                    LOGGER.severe("output.close() error: "
                            + ServiceUtils.stackToString(f));
                }
            }
        }
    }       
    catch (FTPConnectionClosedException e) {
        LOGGER.severe("Server closed connection: " + server + " "
                + ServiceUtils.stackToString(e));
        throw e;
    } catch (IOException e) {
        LOGGER.severe("IOException, server: " + server + " "
                + ServiceUtils.stackToString(e));
        throw e;
    } finally {
        if (loggedIn) {
            try {
                ftp.logout();
            } catch (IOException f) {
                LOGGER.severe("ftp.logout() error: "
                        + ServiceUtils.stackToString(f));
            }
        }
        disconnect(ftp);
    }
}

我的問題基本上是,retrieveFile()方法是否失敗,無論如何我都可以重新連接並從斷開連接的地方開始下載。

現在,我使用Microsoft IIS服務器作為FTP服務器,但是在生產環境中,它將是FileZilla FTP服務器。

任何幫助表示贊賞。 謝謝

抱歉,回復太晚了。 這是我為解決問題所做的工作:

  1. 設置FileZilla服務器
  2. 使用retrieveFileStream而不是retrieveFile。
  3. 保持寫入的字節數,並使用相同的輸出流進行寫入。

      BufferedInputStream inputStream = null; BufferedOutputStream outputStream = null; InputStream in = null; int osCount = 0; in = ftp.retrieveFileStream(remote); inputStream = new BufferedInputStream(in); File localFile = new File(local, fileName); outputStream = new BufferedOutputStream(new FileOutputStream(localFile)); for (int read = inputStream.read(); read != -1; read = inputStream.read()) { outputStream.write(read); osCount++; } outputStream.flush(); if (osCount < fileSize) { System.out.println(fileName + ": Errored out !!!"); BufferedInputStream inputStream1 = null; InputStream in1 = null; if (ftp.isConnected()) { try { while (osCount < fileSize && new Date().getTime() < (startTime_ms + TOTAL_DURATION_MSECS)) { try { disconnect(ftp); ftpConnect(server, ftp, port, startTime_ms); ftp.login(username, password); ftp.setRestartOffset(osCount); System.out.println(fileName + ": Re reading from position " + osCount); in1 = ftp.retrieveFileStream(remote); inputStream1 = new BufferedInputStream(in1); for (int read = inputStream1.read(); read != -1; read = inputStream1.read()) { outputStream.write(read); osCount++; } outputStream.flush(); if(FTPReply.isPositiveCompletion(ftp.getReplyCode())){ isErrored = true; break; } } catch (Exception e1) { Thread.sleep(1000); LOGGER.severe(fileName + ": File not downloaded " + server + " " + ServiceUtils.stackToString(e1)); } } } catch (Exception e) { LOGGER.severe(fileName + ": File not downloaded " + server + " " + ServiceUtils.stackToString(e)); } } } 

FTPCLient.restart(...) protected 我認為setRestartOffset(...)retrieveFile(...)setRestartOffset(...)的方法: “注意:如果您使用過setRestartOffset(long),則文件數據將從選定的偏移量開始。”

我還會捕獲CopyStreamException而不是僅捕獲IOException“ CopyStreamException允許您確定傳輸的字節數 ”。

在進入重試塊之前,請檢查ftp.isConnected() ,但是您寫了“ FTP服務器網絡連接松動,並且可能保持斷開連接” 我猜想,如果您輸入此catch塊,則連接性已經丟失,這就是根本無法進入此塊的原因之一。

ftp.retr(...)在做什么? 重試,是的,但是它能按預期工作嗎?

如果通過以下方式調試代碼,會得到什么?

  • ftp.isConnected()處設置斷點
  • 檢索足夠大的文件以花費一段時間下載
  • 進行傳輸時拔出網絡電纜
  • 查看ftp.isConnected()的值
  • 如果它是true (不太可能,但是誰知道) ftp.retr(...)返回什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM