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.
Advertisement
Answer
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/howto/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.