You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FTPClient类及Selenium下载FTP文件时,如何保留原始修改/创建日期

如何在FTP下载时保留文件原始修改日期(含Selenium场景)

刚好之前处理过类似的需求,尤其是需要用文件修改日期做校验的场景,确实不能让下载后的文件时间变成脚本运行时间。下面分两种情况给你解决方案:


一、Apache Commons Net FTPClient 实现方案

FTPClient本身没有自动同步远程文件修改时间的功能,但我们可以手动获取远程文件的元数据,然后给本地下载后的文件设置对应时间。具体分两步:

1. 获取远程文件的原始修改时间

使用FTPClient的getModificationTime(String remoteFilePath)方法,它会返回一个类似 YYYYMMDDHHMMSS 格式的字符串(比如20240520143000),我们需要把它转换成Java能识别的时间戳。

2. 给本地文件设置修改时间

下载完成后,用File.setLastModified(long timestamp)方法,把本地文件的最后修改时间改成远程文件的时间。

修改后的完整代码

我把你的代码做了调整,加入了时间同步的逻辑:

package oops;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

public class FTPDownloadFileDemo {
    public static void main(String[] args) {
        String server = "test.rebex.net";
        int port = 21;
        String user = "demo";
        String pass = "password";
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            String remoteFile1 = "/readme.txt";
            File downloadFile1 = new File("C:\\project\\readme1.txt");

            // 第一步:获取远程文件的修改时间
            String remoteModTimeStr = ftpClient.getModificationTime(remoteFile1);
            // 注意:getModificationTime返回的格式可能带前缀,比如"213 20240520143000",需要截取后面的时间部分
            if (remoteModTimeStr != null && remoteModTimeStr.contains(" ")) {
                remoteModTimeStr = remoteModTimeStr.split(" ")[1];
            }
            // 解析时间字符串为Date(注意FTP时间默认是UTC时区)
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date remoteModDate = sdf.parse(remoteModTimeStr);
            long remoteModTimestamp = remoteModDate.getTime();

            // 第二步:下载文件
            OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
            boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
            outputStream1.close();

            if (success) {
                // 第三步:设置本地文件的修改时间
                boolean timeSetSuccess = downloadFile1.setLastModified(remoteModTimestamp);
                if (timeSetSuccess) {
                    System.out.println("File #1 downloaded successfully, and original modification time preserved.");
                } else {
                    System.out.println("File downloaded, but failed to set modification time.");
                }
            }
        } catch (IOException | ParseException ex) {
            System.out.println("Error: " + ex.getMessage());
            ex.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

注意点

  • FTP返回的修改时间默认是UTC时区,解析的时候一定要设置时区,否则会有时间偏差。
  • getModificationTime的返回值可能带有前缀(比如213 ),需要先截取有效时间部分。

二、结合Selenium的实现方案

Selenium本身是用来操作浏览器的,它并不直接处理FTP下载。这里分两种场景:

场景1:Selenium做前置操作,用FTPClient下载文件

这种情况最常见,比如先通过Selenium登录系统、触发某个生成文件的操作,再用FTPClient去下载文件并同步时间。这时直接复用上面的FTPClient代码即可,把下载逻辑放在Selenium操作之后:

// 先执行Selenium操作
WebDriver driver = new ChromeDriver();
driver.get("https://your-system-url.com");
// 这里做登录、触发文件生成等操作...
driver.quit();

// 然后执行FTPClient下载并同步时间(就是上面的代码)
FTPClient ftpClient = new FTPClient();
// ... 后续下载和时间同步逻辑 ...

场景2:必须通过浏览器下载FTP文件

如果是通过浏览器访问FTP链接(比如ftp://test.rebex.net/readme.txt)下载文件,浏览器会默认把本地文件的修改时间设为当前时间。这时我们需要:

  1. 先通过FTPClient获取远程文件的修改时间
  2. 找到浏览器下载的本地文件
  3. 给这个文件设置远程文件的修改时间

示例代码片段:

// 第一步:用FTPClient获取远程文件修改时间
FTPClient ftpClient = new FTPClient();
ftpClient.connect("test.rebex.net", 21);
ftpClient.login("demo", "password");
String remoteModTimeStr = ftpClient.getModificationTime("/readme.txt");
// 解析时间的逻辑和上面一样...
long remoteModTimestamp = ...;
ftpClient.disconnect();

// 第二步:用Selenium触发浏览器下载
WebDriver driver = new ChromeDriver();
// 设置浏览器下载路径(避免弹窗)
ChromeOptions options = new ChromeOptions();
options.addArguments("--download.default_directory=C:\\project");
driver = new ChromeDriver(options);
driver.get("ftp://test.rebex.net/readme.txt");
// 等待下载完成(可以通过检查文件是否存在且大小稳定来判断)
Thread.sleep(3000); // 实际项目中建议用显式等待

// 第三步:找到下载的文件并设置修改时间
File downloadedFile = new File("C:\\project\\readme.txt");
downloadedFile.setLastModified(remoteModTimestamp);
driver.quit();

注意点

  • 浏览器下载的文件名可能和远程文件名一致,但如果有重名会自动加后缀(比如readme (1).txt),需要处理这种情况。
  • 等待下载完成的逻辑要严谨,不能只用Thread.sleep,可以循环检查文件的大小是否不再变化,或者用WebDriverWait配合文件存在的条件。

内容的提问来源于stack exchange,提问作者Karthik Deepan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:01:56