2

我每 35 秒在某个目录上运行一个轮询器。这些文件通过 SFTP 服务器放置在此目录中。问题是每当轮询与复制文件的时间冲突时。它还会选择尚未完全复制的不完整文件。

我们可以知道文件的状态是处于复制模式还是复制模式?

4

3 回答 3

2

文件观察者有几种常用策略可以“知道”文件已完全传输

  1. 以时间间隔轮询,如果文件大小在一个时间间隔内没有变化,则认为文件已完全传输。例如,每 1 分钟查看一次文件是否存在。看到文件存在后,每 5 秒监控一次文件的大小。如果文件大小保持不变 30 秒,则将其视为完全传输。

  2. 让传输过程在文件传输后创建一个标记文件。例如,在完成文件传输后FOO.txt,创建一个空的FOO.txt.tag. 您的文件观察者将检查是否存在,FOO.txt.tag一旦存在,您就知道FOO.txt已完全转移

  3. 在文件具有特殊格式(例如特殊的页脚行)的某些特殊情况下,您的文件观察器可以轮询文件并查看最后几行,并查看它们是否与所需的模式匹配

每种方法都有其优点和缺点:

  1. 方法 1 对传输过程的影响最小。有时文件是由第 3 方传输的,您几乎无法像方法 2 那样告诉他们创建标记文件。但是您可以看出这种方法不是 100% 可靠的,尤其是在网络较差的情况下。
  2. 方法2是最可靠的。但是,如前所述,在某些情况下您无法控制转移过程
  3. 方法三只适用于特殊情况

选择适合您需要的那一款

于 2016-02-04T08:14:09.483 回答
1

让轮询器记录文件大小。如果从一轮到下一轮大小没有变化,则文件已完成下载。

你能影响 SFTP 服务器吗?下载完成后是否可以创建标记文件(例如' .thisIsAFile.doc.done')?

于 2016-02-04T07:22:44.947 回答
0

如果您使用 winscp 或 FTP 传输文件,请将此用于 Unix:

public static void isFileReady(File entry) throws Exception {
        long realFileSize = entry.length();
        long currentFileSize = 0;
        do {
            try (FileInputStream fis = new FileInputStream(entry);) {
                currentFileSize = 0;
                while (fis.available() > 0) {
                    byte[] b = new byte[1024];
                    int nResult = fis.read(b);
                    currentFileSize += nResult;
                    if (nResult == -1)
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("currentFileSize=" + currentFileSize + ", realFileSize=" + realFileSize);
        } while (currentFileSize != realFileSize);
    }
于 2020-08-12T15:47:17.323 回答