在另一个进程尝试移动/复制该文件之前,确保通过ftp传输的文件已完成的最佳方法是什么?
答案 0 :(得分:3)
ftp服务器怎么样?可能是服务器的插件,只要在文件传输完成时收到肯定的完成回复(2xx服务器返回),就会触发事件。
通过ftp发送文件可以在不知道的时间内中断和暂停,你永远不能假设它们已经完成。我认为唯一可以通过ftp服务器来完成(甚至没有错误的文件传输)的唯一方法。
答案 1 :(得分:1)
1)如果您控制发送;一旦你发送了实际文件,ftp控制空文件具有相同的名称但不同的.ext。测试此控制文件和实际文件是可以的。
2)作为额外的测试;检查文件使用期限并在处理前等待30秒,这可能是避免网络文件锁定延迟的必要条件。
代码示例解释2)
const
LastWriteAccessDwell = 30; // seconds
var
SR: TSearchRec;
LastAccess: TDateTime;
...
if LastWriteWithin( SR.FindData.ftLastWriteTime, LastWriteAccessDwell, LastAccess ) then
begin
WriteText( format('Last Access @%s was less than %d seconds.', [DateTimeToStr(LastAccess), LastWriteAccessDwell]) );
continue;
end;
function LastWriteWithin( FileTime: TFileTime; const Seconds: Cardinal; out LastAccess: TDateTime ): boolean;
var
LocalFileTime: TFileTime;
iFileAge: integer;
begin
if Not( FileTimeToLocalFileTime( FileTime, LocalFileTime )
and FileTimeToDosDateTime(LocalFileTime, LongRec(iFileAge).Hi, LongRec(iFileAge).Lo) ) then
RaiseLastOSError;
LastAccess:= FileDateToDateTime(iFileAge);
result:= WithinPastSeconds( Now, LastAccess, Seconds );
end;
答案 2 :(得分:0)
不确定您的FTP服务器是如何工作的,但我会定期检查您是否可以独占打开该文件,因为它可能在文件传输过程中打开并在完成时关闭。
答案 3 :(得分:0)
我经常做以下事情;
a) get the size of the file, in bytes b) append this to the filename eg MyFile.Dat.16384 c) send the file over ftp etc
在另一端,你有一个程序正在观看FTP传入文件夹。每隔一秒左右(调整到适合),您扫描文件夹中的文件,当您找到文件大小与文件名末尾的字符串匹配的文件时,您可以合理地确定它已到达并可以自由移动,重命名,不管。
我们在扫描中构建了一些逻辑,使得文件直到第二次在扫描中出现时才被扑倒,只是为了确保FTP的可能处理/解锁的最后一秒左右服务器
对于Delphi来说,这是相当简单的,它实际上只是一个循环中的findfirst / findnext / findclose类型结构,在计时器上运行。开始扫描时关闭计时器,完成后重新启动计时器。
答案 4 :(得分:0)
通过在发送方一侧生成校验和(MD5,sha1等),可以增强robsoft的答案。一旦接收器看到filename.16384 = filesize 16384,它也可以比较校验和100%确定文件到达好了!
@Linux:见sha1sums,md5sums