使用FTP FTPClient使FTP服务器返回按时间戳列出的文件

我已经编写了下面的代码来连接远程FTP服务器(CentOS 6中的vsftp)。 (为简洁起见,此处未显示exception处理)

FTPClient ftpClient = new FTPClient(); ftpClient.setConnectTimeout(20000); ftpClient.connect(serverip); ftpClient.enterLocalPassiveMode(); ftpClient.login(username, password); if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { ftpClient.disconnect(); throw new FTPConnectionClosedException("Unable to connect to FTP server..."); } FTPFile[] filesList = ftpClient.listFiles(); for (FTPFile tmpFile : filesList) { if (tmpFile.isDirectory()) continue; // processing the file } if (ftpClient.isConnected()) ftpClient.disconnect(); 

如果该FTP服务器中有100个文件,则此listFiles()根据字母顺序给出文件名列表。

 A.txt B.txt Z.txt a.txt z.txt 

有没有办法根据修改时间获取文件? (即最早的文件)。 此listFiles()使用LIST命令。 是否有其他命令可根据修改时间列出文件。 由于这是一个Linux服务器,我们可以发送一些Linux命令来实现这一目标吗?

我已经检查了问题从ftp获取最新文件 。 这种方法的问题是我们必须使用Comparator对文件进行排序,然后重命名并将其移动到另一个文件夹(以修改顺序获取它们)。 如果文件超过1000个,那么对它们进行排序将是一项耗时的操作!

编辑:
更重要的是,检索文件并对它们进行排序还有另一个问题。 使用ftpFile.getTimestamp()时,它没有seconds信息。 它只准确到几分钟。

没有标准的方法让FTP服务器根据您(或任何)标准对文件进行排序。

虽然有些FTP服务器,特别是ProFTPD和vsftpd,通过LIST命令支持专有标志来对条目进行排序。

这两个服务器都支持-t标志,以按修改时间对文件进行排序:

 LIST -t 

虽然这不仅是非标准的,但它实际上违反了FTP协议。

有关ProFTPD支持的所有选项,请参见其手册页:
http://www.proftpd.org/docs/directives/linked/config_ref_ListOptions.html

请注意,vsftpd仅支持-a-r-t-F-l ,其含义与ProFTPD相同。

Apache Commons Net没有API为LIST命令添加标志(唯一的例外,与此问题无关,是-a标志 – 在设置FTPClient.setListHiddenFiles时发送)。

您必须覆盖FTPClient.getListArguments以注入自己的标志。


尽管如此,我还没有看到使用Comparator对文件进行排序有什么问题。 只需确保使用FTPClient.mlistDir() ,它在内部使用现代MLSD命令。 通过这种方式,您可以获得精确的时间戳,而不是精确的时间戳,例如过时的LISTFTPClient.listFiles()

 FTPFile[] remoteFiles = ftpClient.mlistDir(remotePath); Arrays.sort(remoteFiles, Comparator.comparing((FTPFile remoteFile) -> remoteFile.getTimestamp()).reversed()); 

但是,正如您所评论的那样,vsftpd不支持MLSD (ProFTPD)。 在这种情况下, LIST -t确实是获得精确排序文件的唯一有效(尽管又一次,不是标准/可移植)方式。 除了耗时的MDTM调用 – 每个列出的文件的FTPClient.getModificationTime 。 如果你没有精确的时间戳,可以使用与上面相同的代码,但使用FTPClient.listFiles()

另请参阅使用FTPClient.getModificationTime获取FTP服务器中文件的上次修改日期 。