即使从 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。所以我建议你进行并行连接并从那里下载。
这是一个代码片段。
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。所以我建议你进行并行连接并从那里下载。