Java使用FTPClient下载FTP文件前,如何不通过getModificationTime获取文件时间
首先先理清楚通用逻辑:FTP协议本身提供了几种命令来获取文件元数据,比如LIST(标准列表命令,返回文件基本信息包括修改时间)、MDTM(专门获取修改时间)、MLST/MLSD(获取更丰富的元数据,可能包含创建时间)。不过不同FTP服务器对这些命令的支持程度不一样,这是我们要先明确的前提。
回到你提到的Java环境下用org.apache.commons.net.ftp.FTPClient的问题,如果你发现getModificationTime()方法不好用,大概率是你的FTP服务器不支持MDTM命令(这个方法底层就是调用MDTM),或者路径格式有问题。下面分享几个我踩过坑后总结的靠谱替代方案:
方案1:用listFiles()获取FTPFile对象(兼容性最好)
这个方法是最稳妥的,几乎所有FTP服务器都支持LIST命令。listFiles()会返回FTPFile数组,每个FTPFile对象里包含了文件的最后修改时间(通过getTimestamp()方法获取)。
需要注意:不同FTP服务器返回的列表格式差异很大(比如Unix和Windows格式完全不同),如果默认解析失败,你需要手动设置对应的解析器:
import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.UnixFTPEntryParser; // 对应Unix服务器 // import org.apache.commons.net.ftp.WindowsFTPEntryParser; // 对应Windows服务器 public class FtpTimeDemo { public static void main(String[] args) throws Exception { FTPClient ftpClient = new FTPClient(); ftpClient.connect("your-ftp-host", 21); ftpClient.login("username", "password"); // 根据你的FTP服务器系统,设置对应的文件列表解析器 ftpClient.setListParser(new UnixFTPEntryParser()); // 替换成你要查询的文件路径(绝对/相对路径都可,看服务器配置) FTPFile[] files = ftpClient.listFiles("/path/to/target/file.txt"); if (files != null && files.length > 0) { FTPFile targetFile = files[0]; // getTimestamp()返回Calendar对象,包含最后修改时间 java.util.Calendar lastModifiedCal = targetFile.getTimestamp(); java.util.Date lastModifiedDate = lastModifiedCal.getTime(); System.out.println("文件最后修改时间:" + lastModifiedDate); } ftpClient.logout(); ftpClient.disconnect(); } }
方案2:用MLST命令获取更丰富的元数据(包括创建时间)
如果你的FTP服务器支持MLST命令(可以通过ftpClient.hasFeature("MLST")快速检查),那你可以获取到更多元数据,比如文件创建时间(如果服务器提供的话)。
你可以直接调用mlistFile()方法,或者手动发送MLST命令解析返回结果:
// 先检查服务器是否支持MLST if (ftpClient.hasFeature("MLST")) { FTPFile file = ftpClient.mlistFile("/path/to/target/file.txt"); if (file != null) { // 原始返回内容会包含modify、create等字段(不同服务器字段名可能略有差异) String rawListing = file.getRawListing(); System.out.println("MLST返回的元数据:" + rawListing); // 解析创建时间示例 if (rawListing.contains("create=")) { String createTimeStr = rawListing.split("create=")[1].split(";")[0]; // 格式通常是YYYYMMDDHHMMSS,比如20240520143000 java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss"); java.util.Date createDate = sdf.parse(createTimeStr); System.out.println("文件创建时间:" + createDate); } } }
补充:再试试getModificationTime()的正确姿势
如果你还是想尝试getModificationTime(),先确认传入的路径是否正确(比如是不是绝对路径,有没有包含特殊字符)。这个方法返回的是YYYYMMDDHHMMSS格式的字符串,解析后就能转成Date:
String timeStr = ftpClient.getModificationTime("/path/to/file.txt"); if (timeStr != null) { java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss"); java.util.Date modifiedDate = sdf.parse(timeStr); System.out.println("修改时间:" + modifiedDate); }
总结一下:优先用方案1,兼容性拉满;如果需要创建时间,再看服务器是否支持MLST用方案2;方案3可以作为备选,但依赖服务器对MDTM的支持。
内容的提问来源于stack exchange,提问作者User412387




