当前位置:主页>仓库管理软件> 列表

如何提高200万行文本文件的处理速度 找管家婆仓库软件

财务软件版1楼: 我有一个200多万行的文本文件,需要通过比对每一行的部分信息,取出符合条件的该行记录,想请问有没有什么好的方法。
文件的大概内容如下:
235631|83860018|一串字符|字符信息|........
每行的信息格式都一样
我需要通过比对第一个分割符后的四个字符,如果符合条件,将该行信息取出来。

我在DELPHI中的实现方法如下:
RichEdit1:放入该200多万行的文本文件
RichEdit2:存放符合条件的文本信息
我是通过提取RichEdit1中的每一行,通过比对,如果符合条件就件该行放入RichEdit2中。

处理过程中发现,刚开始时的处理速度还可以,以后越来越慢,到后来几乎就不动了。
我电脑的配置还可以:P4 2.8 768M内存

小弟愚笨,不知道各位大侠们有没有什么好的处理方法,希望不吝赐教。

2楼: 使用sqlserver的导入导出工具,先导入到sqlserver数据库里,规范化处理后,直接用sql语句快多了.
我经常用这个方法处理100多M的文本文件的统计信息 如设备维修管理软件

3楼: 建议使用数据库 oracle 或者 sqlserver

4楼: 一般这样的导入导出需要多长时间

5楼: 用数据库,不能用RichEdit空间

6楼: 先收藏

财务软件版7楼: 我来试试看

8楼: 不要用RichEdit,也别用数据库,别把简单的事情复杂话了。用字符串列表TStrings,程序和你的RichEdit差不多,但几秒就算完了。

9楼: 1 数据库是一个办法。


2 另外一个办法就是AssignFile,通过操作无类型文件进行对比,速度也是可以的。
总之肯定不能把这么大个文件刷刷的导入到内存里面,呵呵

10楼: 我在DELPHI中的实现方法如下:
RichEdit1:放入该200多万行的文本文件
RichEdit2:存放符合条件的文本信息

这个装入过程本身就很慢,更是占用内存。
可以直接打开一个文件对象读一下就可以,
移动一下位置指针,这样应该很快的,也无需用TStringList之类的。

11楼: To red03hunter;风林坡;阿拉宁波人
怪小弟愚笨,能给出具体的方法,程序吗,谢谢啦!

12楼: 继续 如管家婆仓库软件

13楼: 这种处理很简单的,没必要用数据库呀。再说如果处理得当的话,直接处理字符串也要比用数据库快得多。只是不知道楼主所说的“选取条件”指的是什么,能不能给出一个具体的条件出来?另外你说的“我需要通过比对第一个分割符后的四个字符”是不是指“83860018”的前四个字符也就是“8386”呀?说下你的具体要求吧,不是很难的,今天上班没啥事,帮你写个程序练练手筋。

财务软件版14楼: To 李奇
具体的要求如下:
235631|83860018|一串字符|字符信息|........
235631|83850018|一串字符|字符信息|........
235631|86090018|一串字符|字符信息|........
......
235631|83810018|一串字符|字符信息|........
235631|52100018|一串字符|字符信息|........
235631|52280018|一串字符|字符信息|........

我想取出所有以“8609”或以“5228”开头的行信息
谢谢啦!

15楼: 已经调试过了,可以实现你的要求.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
RichEdit2: TRichEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
Function ReturnStr(str:String):Boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
FileStream:TextFile;


Temp,str:String;
begin
AssignFile(FileStream,''d:\abcd.txt'');
Reset(FileStream);
while not SeekEof(fileStream) do
begin
Readln(FileStream,temp);

if ReturnStr(temp)<>false then
RichEdit2.Lines.Add(temp);
end;
CloseFile(FileStream);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RichEdit1.Lines.Clear;
RichEdit2.Lines.Clear;

end;

function TForm1.ReturnStr(str: String): Boolean;
Var
loc_str_Str:String;
begin
if Str<>'''' then
begin
loc_str_Str:=Copy(Str,pos(''|'',str)+1,4);
if (loc_str_Str=''8609'') or (loc_str_Str=''5228'') then
begin
Result:=true;
end else
Result:=false;

end;
end;

end.

16楼: 假设你的源文本已经放在RichEdit1里面,另外还有一个RichEdit2等待存放处理结果。那么用一个过程来提取符合条件的字符串的话就是--

procedure TForm1.Button1Click(Sender: TObject);
var
temps:string;


temps1:string[4];
ps,pd:Pointer;
psi,psi_,pdi,i:integer;
begin
ps:=Pointer(RichEdit1.Text);
psi:=0;
SetLength(temps,Length(RichEdit1.Text));
pd:=Pointer(temps);
pdi:=0;
Repeat
psi_:=psi;
While not (ps[psi] in [#0,''|'',#13,#10]) do
inc(psi);
case ps[psi] of
#0:
Break;
''|'':
begin
for i:=1 to 4 do
temps1[i]:=ps[psi+i];
if (temps1=''8609'') and (temps1=''5228'') then
begin
for i:=psi_ to psi do
begin
pd[pdi]:=ps[i];
inc(pdi)
end;
inc(psi);
While not (ps[psi] in [#0,#13,#10]) do
begin
pd[pdi]:=ps[psi];
inc(pdi);
inc(psi)
end;
case ps[psi] of
#13:
if ps[psi+1]=#10
begin
pd[pdi]:=#13;
pd[pdi+1]:=#10;
pdi:=pdi+2;
psi:=psi+2
end
else
begin
pd[pdi]:=#13;
inc(pdi);
inc(psi)
end;
#10:
begin
pd[pdi]:=#10;
inc(pdi);
inc(psi)
end
end
end
else
begin
Repeat
inc(psi)
Until ps[psi] in [#0,#13,#0];
case psi[psi] of
#13:
if ps[psi+1]=#10
psi:=psi+2
else
inc(psi);
#10:
inc(psi)
end
end
end;
#13:
if ps[psi+1]=#10
psi:=psi+2
else
inc(psi);
#10:
inc(psi)
end
Until ps[psi]=#0;
SetLength(temps,pdi);
RichEdit2.Text:=temps
end;
这种处理方法的速度是比较快的。不过要注意的一点就是,你的原文本必须是每行信息都要用换行回车来分开。

17楼: 呵呵,这个用B+树把,用B+树是效率最高的办法,数据库就用这个做索引。

18楼: 多人接受答案了。