即使从 ftp 服务器下载其文件后,线程也不会与服务器断开连接,并且不会重新使用自身来下载另一个文件

Thread is not disconnecting from server even after its file is downloaded from ftp server and not reusing itself to download another one

这是一个代码片段。

FtpDownloader.java

ExecutorService pool = Executors.newFixedThreadPool(5);

 for (FTPFile file : files) {
     if (!file.isFile()) continue;
     pool.submit(new FtpFileDownloader(file));
}

FTPFileDownloader.java


public class FtpFileDownloader implements Runnable{
    static Logger logger = LoggerFactory.getLogger(FtpFileDownloader.class);

    private FTPFile file;

    public FtpFileDownloader(FTPFile file) {
        this.file = file;
    }

    private OutputStream outputStream;

    @Override
    public void run() {
        try{
            long start = System.currentTimeMillis();
            String fileName = file.getName();
            logger.info("File is {}", fileName);

            outputStream = new BufferedOutputStream(new FileOutputStream("/home/user/Downloads/" + "FtpDownloads" + "/" + fileName));

            //get the file from the remote system
            ftpClient.retrieveFile(fileName, outputStream);

            showServerReply(ftpClient);
            logger.info("[{}ms, {} processing finished.]",System.currentTimeMillis()-start,fileName);


        }catch (Exception e){
            logger.info("FtpFileDownloader expection");
            e.printStackTrace();
        }finally {
            try {
                //close output stream
                outputStream.close();
            } catch (IOException e) {
                logger.info("Io exception happened");
                e.printStackTrace();
            }
        }

我已经创建了一个大小为 5 的固定线程池。 所以在每个服务器从服务器下载5个文件后

即使在下载文件并等待 FTP 服务器断开连接后,线程也不会与服务器断开连接

2022-03-01 15:49:33.584  INFO 10931 --- [pool-1-thread-5] t.a.f.listener.ftp.FtpFileDownloader     : File is mail-send-winforms.png
2022-03-01 15:49:33.587  INFO 10931 --- [pool-1-thread-4] t.a.f.listener.ftp.FtpFileDownloader     : File is mail-editor.png
2022-03-01 15:50:33.769  INFO 10931 --- [pool-1-thread-1] t.a.f.listener.ftp.FtpFileDownloader     : FtpFileDownloader expection
2022-03-01 15:50:33.771  INFO 10931 --- [pool-1-thread-1] t.a.f.listener.ftp.FtpFileDownloader     : File is mime-explorer.png
java.net.SocketTimeoutException: Connect timed out
    at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:546)
    at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
    at java.base/java.net.Socket.connect(Socket.java:633)
    at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:866)
    at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:971)
    at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:3308)
    at tech.adoptnet.ftppractice.listener.ftp.FtpFileDownloader.run(FtpFileDownloader.java:35)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)

下载文件后,每个线程都在等待连接超时,然后再去下载其他文件。

如何让线程在没有连接超时的情况下重新使用自己?

我想我明白你想要做什么了。首先,FTP 本身并不能让您同时使用多个连接(参考 )。

你所做的也不是thread-safe。所以我建议你进行并行连接并从那里下载。