问题描述
我已经编写了下面的代码来连接远程FTP服务器(CentOS 6中的vsftp)。 (为简洁起见,此处不显示异常处理)
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(20000);
ftpClient.connect(serverip);
ftpClient.enterLocalPassiveMode();
ftpClient.login(用户名,密码);
if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
ftpClient.disconnect();
抛出新的FTPConnectionClosedException(无法连接到FTP服务器...);
}
FTPFile [] filesList = ftpClient.listFiles();
for(FTPFile tmpFile:filesList){
if(tmpFile.isDirectory())
continue;
//处理文件
}
if(ftpClient.isConnected())
ftpClient.disconnect();
如果FTP服务器中有100个文件,则 listFiles()
根据字母顺序给出文件名列表。
A.txt
B .txt
Z.txt
a.txt
z.txt
是否有任何方法根据修改后的时间获取文件?(即最早的文件首先)。这 listFiles()
使用 LIST
命令。 是否有其他命令可用于根据修改时间列出文件?因为这是一个Linux服务器,我们可以发送一些Linux命令来实现吗?
Comparator
命令文件,然后重命名并将其移动到另一个文件夹中(以修改顺序获取它们)。如果有超过1000个文件,排序它们将变成一个耗时的操作! 编辑:
另外,检索文件和排序他们有另一个问题。当使用 ftpFile.getTimestamp()
时,它没有秒
信息。这是准确的只有分钟。
没有标准的方法让FTP服务器根据您的(或任何)标准。
尽管一些FTP服务器,特别是ProFTPD和vsftpd,支持使用 LIST
命令的专有标志,排序条目。
这两个服务器都支持 -t
标志对文件进行修改时间排序:
LIST -t
虽然这不仅是非标准的,但它实际上违反了FTP协议。
对于ProFTPD支持的所有选项,请参见其手册页: >
请注意,vsftpd仅支持 -a
, -r
, -t
, -F
和 -l
与ProFTPD具有相同的含义。
Apache Commons Net没有向 LIST $添加标志的API c $ c>命令(唯一的例外,与这个问题无关,是
-a
标志 - 当 FTPClient.setListHiddenFiles
已设置)。
您必须覆盖对文件进行排序。只要确保你使用,它在内部使用现代 MLSD
命令。这样你就可以得到精确的时间戳,而不是精确的时间戳,例如过时的 LIST
- 。
FTPFile [] remoteFiles = ftpClient.mlistDir(remotePath);
Arrays.sort(remoteFiles,
Comparator.comparing((FTPFile remoteFile) - > remoteFile.getTimestamp())。reversed());
虽然如您所说,vsftpd不支持 MLSD
(ProFTPD)。在这种情况下, LIST -t
确实是获取精确排序文件的唯一有效方法(虽然也是非标准/便携式)。除了耗时的调用 MDTM
- 文件。如果你没有精确的时间戳,那么可以使用与上面相同的代码,但是使用 FTPClient.listFiles()
。
另请参阅。
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();
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
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?
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!
Edit:
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.
There's no standard way to have the FTP server sort the files according to your (or any) criteria.
Though some FTP servers, notably the ProFTPD and vsftpd, support proprietary flags with the LIST
command to sort the entries.
Both these servers support the -t
flag to sort the files by a modification time:
LIST -t
Though this is not only non-standard, it actually violates the FTP protocol.
For all options supported by ProFTPD, see its man page:
http://www.proftpd.org/docs/directives/linked/config_ref_ListOptions.html
Note that vsftpd supports only -a
, -r
, -t
, -F
and -l
with the same meaning as ProFTPD.
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).
You would have to override the FTPClient.getListArguments
to inject your own flags.
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());
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.
See also Fetching last modified date of a file in FTP server using FTPClient.getModificationTime yields null.
这篇关于使用Apache FTPClient使时间戳列出FTP服务器返回的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!