【发布时间】:2013-11-21 19:43:10
【问题描述】:
今天早些时候,我在这里提出了一个问题,询问我在计算机中扫描文件的方法是否正确。作为解决方案,我收到了一些提示,我认为的解决方案之一是:“这需要紧急解决!”,是说内存溢出,一旦我完全读取内存中的文件。所以我开始尝试找到一种方法来逐个读取文件,但我得到了一些东西(错误/虚假),我需要一些帮助来弄清楚如何正确地做到这一点。 这个方法现在很简单:
procedure ScanFile(FileName: string);
const
MAX_SIZE = 100*1024*1024;
var
i, aux, ReadLimit: integer;
MyFile: TFileStream;
Target: AnsiString;
PlainText: String;
Buff: array of byte;
TotalSize: Int64;
begin
if (POS('.exe', FileName) = 0) and (POS('.dll', FileName) = 0) and
(POS('.sys', FileName) = 0) then //yeah I know it's not the best way...
begin
try
MyFile:= TFileStream.Create(FileName, fmOpenRead);
except on E: EFOpenError do
MyFile:= NIL;
end;
if MyFile <> NIL then
try
TotalSize:= MyFile.Size;
while TotalSize > 0 do begin
ReadLimit:= Min(TotalSize, MAX_SIZE);
SetLength(Buff, ReadLimit);
MyFile.ReadBuffer(Buff[0], ReadLimit);
PlainText:= RemoveNulls(Buff); //this is to transform the array of bytes in string, I posted the code below too...
for i:= 1 to Length(PlainText) do
begin //Begin the search..
end;
dec(TotalSize, ReadLimit);
end;
finally
MyFile.Free;
end;
end;
RemoveNulls 的代码是:
function RemoveNulls(const Buff: array of byte): String;
var
i: integer;
begin
for i:= 0 to Length(Buff) do
begin
if Buff[i] <> 0 then
Result:= Result + Chr(Ord(Buff[i]));
end;
end;
好的,到目前为止我遇到的问题是:
1- 每次重复 while 时,我都会消耗更多的内存,而我原本期望只有 MAX_SIZE 变量中描述的 MAX 100MB,对吧?
2- 我创建了一个文件,其中出现了 2 次应过滤的内容,但由于某种未知原因,我得到了大约 10 次重复出现,看起来我正在重复扫描文件。
感谢您的帮助,如果有人已经完成了此类代码,请在此处发布,我不假装重新创建轮子...
【问题讨论】:
-
参见@DavidHeffernan 的
Buffered files (for faster disk access)。 -
那是我不明白的大量代码。我知道它可以解决我的问题,但如果可能的话,我更喜欢做一些简单的事情。感谢您的关注。
-
Re: 2) 和 4) 那是因为您从文件中请求正好 100MiB,而您必须请求
Min(Count, MAX_SIZE)。我建议重写(为了练习简单,暂时不要处理异常)。 -
@FreeConsulting 是的,我现在做到了:
while Count > 0 do begin N:= Min(Count, MAX_SIZE); SetLength(Buff, N); MyFile.ReadBuffer(Buff[0], N);它解决了 2 和 4...谢谢! -
请不要在进行过程中修改问题,cmets 中的“2) 和 4)”现在没有多大意义。
标签: delphi