当前位置: 首页 > 面试题库 >

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

晏炳
2023-03-14
问题内容

我已将以下代码编写为连接到远程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获取最新文件的问题。这种方法的问题在于,我们必须先使用a排序文件,Comparator然后重命名并将其移动到其他文件夹(以修改顺序获取它们)。如果文件超过1000个,则对它们进行排序将成为一项耗时的操作!

编辑:
而且,检索文件并对文件进行排序还有另一个问题。使用seconds时没有任何信息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()可以。



 类似资料:
  • 我们有一个ftp服务器,下面只有很少的目录和文件,我可以通过浏览器连接并成功访问目录。但是,当使用同一服务器时:具有凭据的端口无法连接。还尝试使用JSR233采样器列出文件,但没有成功。 请引导。 TestPlan:FTP请求默认值(服务器IP和端口:21) 对于FTP请求,获取如下错误:响应消息:java。木卫一。FileNotFoundException:(系统找不到指定的路径)请求正在进行:

  • 我们将MySQL connector J从5.1.46版本升级到8.0.16。我们的web服务器时区是UTC,现在mysql服务器在IST时区,在升级驱动程序之前,驱动程序的时间戳列值只在UTC中持久化(使用hibenate),但是在移动到J8驱动程序之后,它被保存到mysql服务器时区,即IST。 我们只希望以UTC形式存储/提取时间戳值。

  • 问题内容: 民间, 我试图了解MomentJS API。在机器上获取当前时间的合适方法是什么? 与 试图解析他们的文档,并且不清楚使用什么。 http://momentjs.com/docs/#/query/is-a- moment/ 问题答案: 在这里,您要为CurrentDate分配一个momentjs实例: 这里只是一个字符串,是momentjs实例的默认格式的结果: 这里是自一月…以来的秒

  • 我正在写一个涉及多个客户的应用程序。一个客户端使用FTP将文件上传到服务器,然后另一个客户端下载并删除该文件。我使用FTP服务器作为一种中间人来交换信息,因为我不希望用户必须向前移植。我已经知道如何上传文件,但我不知道如何删除文件。使用FTP删除文件的命令是: 我试过这么做,但没有成功。以下是我尝试过的代码: 我有一种感觉 我在这个网站上读到了关于类似问题的其他问题,所有的回答都告诉我使用图书馆。

  • 我尝试使用外部Web服务对pdf进行数字签名。此Web服务包含用户证书,用户可以使用他们的凭据和一次性密码生成的代码访问该证书。 旁注:web服务应该期望pdf摘要(哈希),但奇怪的是,它却接受整个文件。 无论如何,实现如下: pdf已成功签名,但使用Adobe Reader并检查签名字段时,似乎缺少可信时间戳,如图所示: 看起来,来自远程服务的响应是一个签名对象,我只需要将其嵌入到PDF文件中。