使用FTP FTPClient使FTP服务器返回按时间戳列出的文件
我已经编写了下面的代码来连接远程FTP服务器(CentOS 6中的vsftp)。 (为简洁起见,此处未显示exception处理)
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个,那么对它们进行排序将是一项耗时的操作!
编辑:
更重要的是,检索文件并对它们进行排序还有另一个问题。 使用ftpFile.getTimestamp()
时,它没有seconds
信息。 它只准确到几分钟。
没有标准的方法让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()
。
另请参阅使用FTPClient.getModificationTime获取FTP服务器中文件的上次修改日期 。