本文介绍了使用 Apache FTPClient 使 FTP 服务器返回按时间戳列出的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了以下代码来连接到远程 FTP 服务器(CentOS 6 中的 vsftp).(为简洁起见,这里没有展示异常处理)

I have written this below code to connect to a remote FTP Server (vsftp in CentOS 6). (For brevity Exception handling is not shown here)

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() 根据字母顺序给出文件名列表.

If there are 100 files in that FTP server, this listFiles() gives the list of file names according to the Alphabetical order.

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

有没有办法根据修改时间获取文件?(即最旧的文件优先).这个 listFiles() 使用 LIST 命令.是否有其他命令可以根据修改时间列出文件?既然这是一个Linux服务器,我们可以发送一些Linux命令来实现吗?

Is there any way to get the files according to the modified time? (i.e. oldest files first). This listFiles() uses LIST command. Is there any other command available to list the files according to the modification time.? Since this is a Linux server, can we send some Linux commands to achieve this?

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

I have already checked question get latest file from ftp. The problem with this approach is that we have to order the files using a Comparator then rename and move it a different folder (To get them in the modification order). If there are more than 1000 files, sorting them would become a time consuming operation!


而且,检索文件并对其进行排序还有另一个问题.当使用 ftpFile.getTimestamp() 时,它没有 seconds 信息.它只精确到分钟.


And more over, retrieving the files and sorting them has another problem. It doesn't have seconds information when ftpFile.getTimestamp() is used. It is accurate only to minutes.

推荐答案

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

There's no standard way to have the FTP server sort the files according to your (or any) criteria.

尽管一些 FTP 服务器,特别是 ProFTPD 和 vsftpd,支持使用 LIST 命令对条目进行排序的专有标志.

Though some FTP servers, notably the ProFTPD and vsftpd, support proprietary flags with the LIST command to sort the entries.

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

Both these servers support the -t flag to sort the files by a modification time:

LIST -t

虽然这不仅不规范,但实际上违反了 FTP 协议.

Though this is not only non-standard, it actually violates the FTP protocol.

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

For all options supported by ProFTPD, see its man page:
http://www.proftpd.org/docs/directives/linked/config_ref_ListOptions.html

注意vsftpd只支持-a-r-t-F-l 与 ProFTPD 含义相同.

Note that vsftpd supports only -a, -r, -t, -F and -l with the same meaning as ProFTPD.

Apache Commons Net 没有用于向 LIST 命令添加标志的 API(唯一的例外,虽然与这个问题无关,是 -a 标志 - 这是FTPClient.setListHiddenFiles 设置时发送).

The Apache Commons Net has no API to add flags to the LIST command (the only exception, while irrelevant to this question, is the -a flag - which is sent when FTPClient.setListHiddenFiles is set).

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

You would have to override the FTPClient.getListArguments to inject your own flags.

尽管如此,我看不出使用 Comparator 对文件进行排序.只要确保你使用 FTPClient.mlistDir(),它在内部使用现代的 MLSD 命令.通过这种方式,您可以获得精确的时间戳,而不是像过时的 LIST - FTPClient.listFiles().

Though again, I do not see what's wrong with using Comparator to sort the files. Just make sure you use FTPClient.mlistDir(), which internally uses a modern MLSD command. This way you get precise timestamps, not minute- or worse precision timestamps like with obsolete 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() 即可.

Though, as you commented, the vsftpd does not support MLSD (ProFTPD does). In that case the LIST -t is indeed the only efficient (although again, not standard/portable) way to get precisely sorted files. Except for a time-consuming call of MDTM - FTPClient.getModificationTime for each listed file. If you can do without precise timestamps, the same code as above, but with FTPClient.listFiles() will do.

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

这篇关于使用 Apache FTPClient 使 FTP 服务器返回按时间戳列出的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 10:52
查看更多