我想终止用户从我的程序中选择的文件。我写了这个示例代码:
var
aFile: TFileStream;
Const
FileAddr: String = 'H:\Akon.mp3';
Buf: Byte = 0;
begin
if FileExists(FileAddr) then
begin
// Open given file in file stream & rewrite it
aFile:= TFileStream.Create(FileAddr, fmOpenReadWrite);
try
aFile.Seek(0, soFromBeginning);
while aFile.Position <> aFile.Size do
aFile.Write(Buf, 1);
finally
aFile.Free;
ShowMessage('Finish');
end;
end;
end;
如您所见,我用0(null)值覆盖给定文件。此代码可以正常工作,但在大文件中速度非常低。我想在多线程代码中执行此过程,但我尝试了一些测试代码而无法执行此操作。例如,我创建了4个执行此操作的线程来加速此过程。
有没有办法加快这个过程?
答案 0 :(得分:4)
我不知道它是否可以帮助你,但我认为你可以做得更好(比多线程)写入更大的缓冲区。
例如,您可以初始化16k宽的缓冲区并直接写入FileStream;你只需要检查文件的最后一部分,你只为其写入完整缓冲区的一部分
相信我,它会更快......
答案 1 :(得分:4)
好的,我会咬人:
const
FileAddr: String = 'H:\Akon.mp3';
var
aFile: TFileStream;
Buf: array[0..1023] of Byte;
Remaining, NumBytes: Integer;
begin
if FileExists(FileAddr) then
begin
// Open given file in file stream & rewrite it
aFile:= TFileStream.Create(FileAddr, fmOpenReadWrite);
try
FillChar(Buf, SizeOf(Buf), 0);
Remaining := aFile.Size;
while Remaining > 0 do begin
NumBytes := SizeOf(Buf);
if NumBytes < Remaining then
NumBytes := Remaining;
aFile.WriteBuffer(Buf, NumBytes);
Dec(Remaining, NumBytes);
end;
finally
aFile.Free;
ShowMessage('Finish');
end;
end;
end;
答案 2 :(得分:3)
多线程在这里不会帮到你。您的约束是磁盘访问,主要是因为您一次只写1个字节。
将Buf
声明为字节数组,并使用FillChar
或ZeroMemory
对其进行初始化。然后按如下方式更改while循环:
while ((aFile.Position + SizeOf(Buf)) < aFile.Size) do
begin
aFile.Write(Buf, SizeOf(Buf));
end;
if (aFile.Position < aFile.Size) then
begin
aFile.Write(Buf, aFile.Size - aFile.Position);
end;
答案 3 :(得分:2)
你应该从以上代码的缓慢中学习:
一次写一个字节是最慢和最差的方法,你会产生巨大的开销,并降低整体性能。
即使一次写1k字节(1024字节),也会有很大的改进,但写一个更大的数量当然会更快,直到你达到收益递减点,我猜是将介于200k和500k之间的写缓冲区大小。了解应用程序停止运行的唯一方法是进行测试,测试和测试。
经常检查位置与大小是完全多余的。如果您读取一次大小并写入正确的字节数,则使用本地变量可以节省更多开销,并提高性能。即,Inc(LPosition,BufSize)增加LPosition:整数逻辑变量,按缓冲区大小量BufSize。
答案 4 :(得分:0)
不确定这是否符合您的要求,但它有效并且速度很快。
var
aFile: TFileStream;
const
FileAddr: String = 'H:\Akon.mp3';
begin
if FileExists(FileAddr) then
begin
aFile:= TFileStream.Create(FileAddr, fmOpenReadWrite);
try
afile.Size := 0;
finally
aFile.Free;
ShowMessage('Finish');
end;
end;
end;
所以这些内容(在函数外声明b
将改善循环中的性能,尤其是在处理大文件时)。我假设在应用filename
中将是var
:
const
b: byte=0;
procedure MyProc;
var
aFile: TFileStream;
Buf: array of byte;
len: integer;
FileAddr: String;
begin
FileAddr := 'C:\testURL.txt';
if FileExists(FileAddr) then
begin
aFile := TFileStream.Create(FileAddr, fmcreate);
try
len := afile.Size;
setlength(buf, len);
fillchar(buf[0], len, b);
aFile.Position := 0;
aFile.Write(buf, len);
finally
aFile.Free;
ShowMessage('Finish');
end;
end;
end;