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

时间:2016-03-16 09:50:17

标签: java ftp apache-commons-net

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

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命令来实现这一目标吗?

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

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

1 个答案:

答案 0 :(得分:3)

没有标准方法让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命令。通过这种方式,您可以获得精确的时间戳,而不是精确的时间戳,例如过时的LIST - FTPClient.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()即可。

另见Fetching last modified date of a file in FTP server using FTPClient.getModificationTime yields null