For my project I need to download a zip file from an FTP server, which releases a new zip about 13 times a year. I need to download the latest file following the server's naming convention:Prefix + release number (one or two digits) + year (two digits) + suffix + ".zip"
for instance:
ALFP1016F.zip
The prefix will always be the same (ALFP) and the suffix either F or P (stands for "full" or "partial"; I need only the files ending with suffix F). On top of that, there are several other files in the directory I need to ignore because they have different prefixes. Then, I need to get the most recent file in the array following this priority order:
For instance, if I have this listing of filenames (full server directory):
1stpage712.pdf
1stpage914.pdf
ALFP1015F.zip
ALFP1015P.zip
ALFP716F.zip
ALFP716P.zip
FSFP816F.zip
FSFP816P.zip
My expected output would beALFP716F.zip
because 16 is the most recent year, and 7 the most recent release number from that year
.
Here's what I've done so far:
//necessary imports
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
//initialize FTP client
ftpClient = new FTPClient();
try {
//connect to server
ftpClient.connect(server, port);
ftpClient.login(username, password);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//list all names from server
String[] filenames = ftpClient.listNames();
//return expected file name
String expectedFileName = returnMostRecent(filenames);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
System.out.println("Disconnected from server");
}
} catch (IOException ex) { ex.printStackTrace(); }
}
I have done a miserable attempt at writing the returnMostRecent(String[])
method, but ended up with an unintelligible mess not worth being posted here.
How can I sort this array and effectively return the most recent file following my priority order?
If you use Java8 you can do:
String file = Arrays.stream(filenames)
.filter(s -> s.startsWith("ALFP") && s.endsWith("F.zip"))
.max(getReleaseComparator())
.orElse(null);
where release comparator is based on extracting numbers from file name and comparing them
I haven't tested this but I think it should work.
private String returnMostRecent(String[] fileNames) {
String file = null;
double version = -1;
for(String name : listNames)
{
// skip files that don't match
if (!name.matches("ALFP[0-9]*F.zip"))
continue;
// get digits only
String digits = name.replaceAll("\\D+","");
// format digits to <year>.<version>
String vstr = digits.substring(digits.length-2,digits.length()) + ".";
if (digits.length() < 4)
vstr += "0";
vstr = digits.substring(0, digits.length()-2);
double v = Double.parseDouble(vstr);
if (v > version)
{
version = v;
file = name;
}
}
return file;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With