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

问题描述 投票:0回答:1

我编写了下面的代码来连接到远程 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命令来实现这一点吗?

我已经检查过问题从 ftp 获取最新文件。这种方法的问题是我们必须使用

Comparator
对文件进行排序,然后重命名并将其移动到不同的文件夹(以使它们按修改顺序排列)。如果文件超过1000个,排序就会变得很耗时!

编辑:
此外,检索文件并对它们进行排序还有另一个问题。使用

seconds
时,它没有
ftpFile.getTimestamp()
信息。仅精确到分钟。

java ftp apache-commons-net
1个回答
4
投票

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

尽管某些 FTP 服务器(尤其是 ProFTPD 和 vsftpd)支持使用

LIST
命令对条目进行排序的专有标志。

这两个服务器都支持

-t
标志来按修改时间对文件进行排序:

LIST -t

虽然这不仅不标准,而且实际上违反了 FTP 协议。

有关 ProFTPD 支持的所有选项,请参阅其手册页:
http://www.proftpd.org/docs/howto/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()
即可。

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

© www.soinside.com 2019 - 2024. All rights reserved.