Java:使用SFTP检查文件是否已完全复制

时间:2016-02-04 07:10:00

标签: java sftp poller

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

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

3 个答案:

答案 0 :(得分:2)

文件监视器有几种常见的策略可以“知道”文件已完全转移

  1. 使用时间间隔进行轮询,如果文件大小在一个间隔内没有变化,则将文件视为完全传输。例如每1分钟注意文件存在。一旦看到该文件存在,则每5秒监视其大小。如果文件大小保持不变30秒,则将其视为完全转移。

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

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

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

    1. 方法1最少影响转移过程。有时文件是由第三方传输的,你几乎没有办法告诉他们如方法2那样创建标记文件。但是你可以说这种方法不是100%可靠,特别是在网络不佳的情况下。
    2. 方法2是最可靠的。但是,如前所述,有些情况下您无法控制转移过程
    3. 方法3仅适用于特殊情况
    4. 选择适合您需求的

答案 1 :(得分:1)

具有轮询器文件大小。如果大小没有从一轮变为下一轮,则文件下载完成。

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

答案 2 :(得分: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);
    }