关于文本文件分解: 谁能帮我分析一下这个问题?(>200分)(200分)

  • 主题发起人 主题发起人 base2
  • 开始时间 开始时间
B

base2

Unregistered / Unconfirmed
GUEST, unregistred user!
问题很简单:一个文本文件比如叫mybook.txt
我想将其分解成mybook01.txt, mybook02.txt, mybook03.txt .......
每个文件包含原来文本文件20000行的数据.
本来用TFileStream应该很容易搞定,但问题是:
这个mybook.txt文件好大, 可能超过一个G!
有没有可以实现的方法?因为我怀疑可能会产生内存溢出的问题
(我的内存可只有128兆那)
望大虾们前来分析指点,3x!
(如果真的很难解决的话,分不够可以再加,偶还有1600分:P)
 
每个文件包含原来文本文件20000行的数据.
[h2]变成2000行[h2]
 
[h2]变成2000行[/h2]
 
>>bzmouse:
您的意思是...?

我的问题是,打个比方: mybook.txt包含10000000行文本信息
那么将分解为mybook0001到mybook1000这样1000个文件,每个文件有20000行
有何良方吗?[?]
 
ft,刚才数字写错了,
源文件应该为20000000行文本[:I]
 
仔细想想应该能解决!?
 
哪位大虾能出出主意?
谢过了先~
 
用文本文件的形式打开
一行以行的读到Tstrings之类中
在存盘
原文件的大小无关紧要

还有一种方法,如果你对每个文件的行数没有严格的要求,可以一无类型文件的方式打开
在1M1M的读如并写进一个无类型文件中,这样做还可以多个线程同时工作,速度会很快的
就象NetAnt一样
 
读一行马上就写一行,不就行了吗??
 
BatchMove 组件
 
不好意思,在UNIX系统中,用SPLIT命令,直接可完成。
 
此方法效率低点,但是可以参考:(程序我没有实际调试)

program cutfile;
var
i,j,n: integer;
f1,f2:textfile;
srcfile,objfile,line: string;
begin
srcfile:='mybook.txt';
n:=2000;
i:=0;
assignfile(f1,srcfile);
while not eof(f1) do
begin
assignfile(f2,'mybook'+inttostr(i)+'.txt');
rewrite(f2);
for j:=1 to n do
begin
if eof(f1) then break;
readln(f1,line);
writeln(f2,line);
end;
closefile(f2);
inc(i);
end;
close(f1);
end.
 
下面的算法应该比较快才对(每次读入4M文本,一边分析一边存入文件)。

procedure TForm1.Button3Click(Sender: TObject);
const
BufSize=1024*1024*4
//4M !!!
ReturnCount=100
//每隔100行生成一个新的文件
var
i,ReadN,n,lastn,FileCount,StartPos,EndPos:Integer;
Buf:array of Byte;
SrcF,DestF:File;
NewFile:Boolean;
PBuf:PByte;
procedure WriteFile;
begin
if EndPos-StartPos>0 then
BlockWrite(DestF,Buf[StartPos],EndPos-StartPos);
if NewFile then
begin
try
CloseFile(DestF);
except
end;
Inc(FileCount);
AssignFile(DestF,'aaa'+IntToStr(FileCount)+'.txt');
Rewrite(DestF,1);
NewFile:=false;
end;
end;
begin
if OpenDialog1.Execute=false then
exit;
SetLength(Buf,BufSize);
AssignFile(SrcF,OpenDialog1.FileName);
FileMode:=fmOpenRead;
Reset(SrcF,1);
Lastn:=0;
FileCount:=1;
StartPos:=0;
EndPos:=0;
FileMode:=fmOpenWrite;
AssignFile(DestF,'aaa'+IntToStr(FileCount)+'.txt');
Rewrite(DestF,1);
NewFile:=false;
while true do
begin
BlockRead(SrcF,Buf[0],BufSize,ReadN);
if ReadN=0 then
begin
CloseFile(DestF);
break;
end;
StartPos:=0;
EndPos:=0;
PBuf:=@Buf[0];
for i:=0 to ReadN-1 do
begin
if PBuf^=13 then
begin
Inc(LastN);
if LastN=ReturnCount then
begin
EndPos:=i;
WriteFile;
NewFile:=true;
LastN:=0;
StartPos:=i+2;
end;
end;
Inc(PBuf);
end;
BlockWrite(DestF,Buf[StartPos],ReadN-StartPos);
end;
CloseFile(SrcF);
end;
 
多人接受答案了。
 
后退
顶部