其他分享
首页 > 其他分享> > 使用Apache FTPClient使FTP服务器返回按时间戳列出的文件

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

作者:互联网

我在下面编写了这个代码来连接远程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个,那么对它们进行排序将是一项耗时的操作!

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

解决方法:

没有标准方法让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.

标签:java,ftp,apache-commons-net
来源: https://codeday.me/bug/20190929/1831092.html