delphi7-如何将写入的文件复制到
-
11-10-2019 - |
题
我有一个应用程序将信息记录到主电脑上每秒的每日文本文件。使用同一应用程序网络上的从属电脑希望将此文本文件复制到其本地驱动器。我可以看到将会有文件访问问题。
这些文件应不得大于30-40MB。网络将是100MB以太网。我可以看到,复制过程可能需要长达1秒钟的时间,这意味着记录PC在读取时需要打开文件以进行编写。
文件编写(记录)和文件复制过程的最佳方法是什么?我知道有标准的Windows CopyFile()过程,但是这给了我文件访问问题。也可以使用FMSHAREDENYNONE标志进行TfileStream,但这也偶尔也会给我一个访问问题(例如每周1个)。
这是完成这项任务的最佳方法?
我当前的文件记录:
procedure FSWriteline(Filename,Header,s : String);
var LogFile : TFileStream;
line : String;
begin
if not FileExists(filename) then
begin
LogFile := TFileStream.Create(FileName, fmCreate or fmShareDenyNone);
try
LogFile.Seek(0,soFromEnd);
line := Header + #13#10;
LogFile.Write(line[1],Length(line));
line := s + #13#10;
LogFile.Write(line[1],Length(line));
finally
logfile.Free;
end;
end else begin
line := s + #13#10;
Logfile:=tfilestream.Create(Filename,fmOpenWrite or fmShareDenyNone);
try
logfile.Seek(0,soFromEnd);
Logfile.Write(line[1], length(line));
finally
Logfile.free;
end;
end;
end;
我的文件复制过程:
procedure DoCopy(infile, Outfile : String);
begin
ForceDirectories(ExtractFilePath(outfile)); //ensure folder exists
if FileAge(inFile) = FileAge(OutFile) then Exit; //they are the same modified time
try
{ Open existing destination }
fo := TFileStream.Create(Outfile, fmOpenReadWrite or fmShareDenyNone);
fo.Position := 0;
except
{ otherwise Create destination }
fo := TFileStream.Create(OutFile, fmCreate or fmShareDenyNone);
end;
try
{ open source }
fi := TFileStream.Create(InFile, fmOpenRead or fmShareDenyNone);
try
cnt:= 0;
fi.Position := cnt;
max := fi.Size;
{start copying }
Repeat
dod := BLOCKSIZE; // Block size
if cnt+dod>max then dod := max-cnt;
if dod>0 then did := fo.CopyFrom(fi, dod);
cnt:=cnt+did;
Percent := Round(Cnt/Max*100);
until (dod=0)
finally
fi.free;
end;
finally
fo.free;
end;
end;
解决方案
我建议不要一开始关闭并重新打开共享文件。由于您每秒都写信给它,所以这只是不必要的开销。
在主侧,创建并关闭文件( fmCreate
标志不能与其他标志一起使用!),然后将其重新打开 fmOpenWrite
模式与 fmShareDenyWrite
分享,打开它并在需要时写信。
在从一侧,打开文件 fmOpenRead
模式与 fmShareDenyNone
分享,打开它,并每秒从中阅读。无需每次通过网络复制整个共享文件。那是浪费的带宽。只需阅读过去几秒钟中编写的任何新数据,仅此而已。如果从属需要将数据存储在本地文件中,则可以独立于共享文件的单独的本地文件,在需要时将新数据推入本地文件。
其他提示
处理您的特定偶尔经常性问题:
您不会说您正在使用哪种版本的Delphi。
tfileStream.create()构造函数(至少)(至少)(至少)都有一个错误。这可能解释了您偶尔的并发问题。
话虽如此,我相信该错误更有可能导致未按预期创建文件(另外指定了ShareMode),这可能会导致您的并发问题。
解决此问题的一种方法是,当需要创建文件时,首先创建文件,然后将其作为单独的构造函数打开以作为单独的构造函数打开 - 这实际上使文件创建是单独的一步,而文件编写过程的一致部分:
if not FileExists(filename) then
begin
// There may be a more efficient way of creating an empty file, but this
// illustrates the approach
LogFile := TFileStream.Create(FileName, fmCreate);
LogFile.Free;
line := Header + #13#10 + s + #13#10;
end
else
line := s + #13#10;
Logfile:=tfilestream.Create(Filename,fmOpenWrite or fmShareDenyNone);
try
logfile.Seek(0,soFromEnd);
Logfile.Write(line[1], length(line));
finally
Logfile.free;
end;
搜索称为“ Isfileinuse”或类似内容的函数,我敢肯定您可以使用以下功能:
// master
while IsFileInUse(*AFileName*) do
Sleep(10);
write-content-to-file
// slave
while IsFileInUse(*AFileName*) do
Sleep(10);
copy-file-to-a-special-location
和Presto!你完成了!!