求最快的读取文件的算法 ( 积分: 100 )

  • 主题发起人 主题发起人 质数
  • 开始时间 开始时间

质数

Unregistered / Unconfirmed
GUEST, unregistred user!
象 UltraEdit-32 读取文件一样,能够以16进制文本的形式显示出来,求最快的算法!

下面的算法很慢。。。
procedure TForm1.Button1Click(Sender: TObject);
var
f : file of byte;
fs,i : Integer;
bytes : array of byte;
tempstr : string;
begin
if OpenDialog1.Execute then
begin
tempstr := '';
assignfile(f,OpenDialog1.FileName);
reset(f);
fs:=filesize(f);//返回的字节数正确
SetLength(bytes,fs);
i := 0;
repeat
seek(f,i);
read(f,bytes);
tempstr := tempstr + ' ' + IntToHex(Bytes,2);
Inc(i);
until i >= fs;
tempstr := Copy(tempstr,2,Length(tempstr));
Memo1.Text := tempstr;
CloseFile(f);
end;
end;
 
试试这个
//////////////////////////////
procedure TForm1.button1Click(sender: TObject)
var
sl : TStringList;
i : int64;
CurrItem : string;
begin
try
sl :=TStringList.Create;
sl.loadFromFile('c:/kkk.txt'); //将你的txt文件读入
for i :=0 to sl.Count-1 do
begin
CurrItem :=sl.Strings; //将当前行赋给变量CurrItem;
//对CurrItem进行你想要的分析
end;
finally
sl.free;
end;
end;
 
首先说说楼主的程序存在的问题:
1、对于大文件(暂时定为超过10M以上),SetLength(bytes,fs);一次申请太大的空间容易失败。(建议分块处理,一次处理够显示看的就行)
2、seek(f,i);导致文件被反复定位,并且这句根本就不需要,文件指针会随着读取自动向后移动。
3、read(f,bytes);一次读一个字节,非常没有效率,将导致频繁地磁盘交互。(建议一次读取一块,然后批量处理,块的大小可以根据实际情况调整)
4、tempstr := tempstr + ' ' + IntToHex(Bytes,2);将导致操作系统频繁地重新分配内存,这是非常没有效率的。(建议一次性分配一块内存,在这块分配好的内存中处理)
5、你的程序将导致操作系统至少要为你分配两倍于你文件大小的内存块(bytes和tempstr),这也不是什么好的策略。

综合来看,你的代码写的实在是不敢恭维,顶多算是在入门级别之前的状态吧,呵呵

对于快速处理文件,可以采用 内存映射 技术,对于大文件的处理,可以一次映射部分文件内容,然后根据用户的实际情况来分批加载剩下的部分。

另外,再送你一语广告语:没有最快,只有更快
呵呵
 
建议你静下心来,好好去看看:
数据结构
Object Pascal参考手册
Delphi开发人员指南
这会让你的程序写的更好些
 
谢谢两位兄台!
尤其谢谢放飞,你说的很好!
 
关于分块读取的,你可以看看TStream类的CopyFrom函数(在Classes单元)
这个函数一次处理$F000(大约60K吧),虽然效率不是最高,但肯定比你上面写的效率要高,呵呵。
 
如果文件过大而且必须都加载进来,你可以考虑在独立的线程中处理加载和对数据处理的过程,而主线程仅仅处理显示数据。
 
嗯,太感谢放飞兄了!!!不过就实现来说,还是比较困难的。。。。
 
后退
顶部