我想处理某个FTP目录,其中包含多个目录,而这些目录又有任意数量的文件。所以我想要做的是有1个线程每个子目录,每个线程各子-DIR在这里所关心的是我想出了:多线程FTP下载
private void fetchFilesFromFTP() {
try {
client.connect("ftp.ncbi.nih.gov");
client.login("anonymous", "anonymous");
client.changeWorkingDirectory("genomes/Fungi");
FTPFile dirs[] = client.listDirectories();
dirsToDl.addAndGet(dirs.length);
for (final FTPFile ftpFile : dirs) {
exec.execute(new Runnable() {
//process each FTP directory in a new thread
@Override
public void run() {
processFTPdir(ftpFile.getName());
}
});
}
} catch (SocketException ex) {
Logger.getLogger(FungiProcessor.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(FungiProcessor.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void processFTPdir(String dir) {
File f = new File(destination + File.separator + dir);
if (!f.mkdirs()) {
System.out.println("Error creating dir for " + dir);
return;
}
FTPFile files[];
try {
//we are already in the correct directory
files = client.listFiles(dir, new FTPFileFilter() {
@Override
public boolean accept(FTPFile ftpf) {
return ftpf.getName().endsWith(".gbk");
}
});
for (FTPFile fTPFile : files) {
FileOutputStream fout = new FileOutputStream(destination + File.separator + dir + File.separator + fTPFile.getName());
if (client.retrieveFile(dir + "/" + fTPFile.getName(), fout)) {
System.out.println("successfully downloaded");
fout.flush();
fout.close();
}
System.out.println(client.getReplyString());
}
} catch (IOException ex) {
Logger.getLogger(FungiProcessor.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if(dirsToDl.decrementAndGet() == 0) latch.countDown();
}
}
代码的顺序版本作品 - 我可以看到以.gbk结尾的文件实际上被下载,而多线程版本只创建了相应的子目录,但没有下载文件。我甚至没有任何错误。 FTP可能一次不支持多个文件下载?
但每个线程使用相同的FTP连接或打开一个单独的连接? – gd1
使用相同的连接。这就是为什么我说我没有现在如果FTP作为协议支持这个 – LordDoskias
通过线程?我非常怀疑它会。所有线程将共享相同的客户端(因此也是相同的命令通道),并且FTP无法提供执行所需的多路复用的方法,以使其工作。 (对两条线程的命令的响应看起来差不多; FTP没有办法说“这是对命令1的响应”。) – cHao