我每 35 秒在某个目录上运行一个轮询器。这些文件通过 SFTP 服务器放置在此目录中。问题是每当轮询与复制文件的时间冲突时。它还会选择尚未完全复制的不完整文件。
我们可以知道文件的状态是处于复制模式还是复制模式?
文件观察者有几种常用策略可以“知道”文件已完全传输
以时间间隔轮询,如果文件大小在一个时间间隔内没有变化,则认为文件已完全传输。例如,每 1 分钟查看一次文件是否存在。看到文件存在后,每 5 秒监控一次文件的大小。如果文件大小保持不变 30 秒,则将其视为完全传输。
让传输过程在文件传输后创建一个标记文件。例如,在完成文件传输后FOO.txt
,创建一个空的FOO.txt.tag
. 您的文件观察者将检查是否存在,FOO.txt.tag
一旦存在,您就知道FOO.txt
已完全转移
在文件具有特殊格式(例如特殊的页脚行)的某些特殊情况下,您的文件观察器可以轮询文件并查看最后几行,并查看它们是否与所需的模式匹配
每种方法都有其优点和缺点:
选择适合您需要的那一款
让轮询器记录文件大小。如果从一轮到下一轮大小没有变化,则文件已完成下载。
你能影响 SFTP 服务器吗?下载完成后是否可以创建标记文件(例如' .thisIsAFile.doc.done
')?
如果您使用 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);
}