78给出能解决问题的人:大大们请进来?(78分)

  • 主题发起人 主题发起人 jj830104
  • 开始时间 开始时间
J

jj830104

Unregistered / Unconfirmed
GUEST, unregistred user!
如下程序是将LISTBOX1的所有文件合成,并且如果其大小是2048的倍数,如果不是则添加'$'补足到2048的倍数,最后在文件头部写上相应的索引:文件名:文件索引(即在本文件的位置):文件大小(真实大小)
我的问题是:文件合成的时候,多于50(大小平均为3M)的时候,程序老是卡住,然后只能强制结束,程序能合成文件但是头部的索引却没有JILL.TXT也没删除.一<问有没更好的方式处理这个需求 2<有没其他的编程方式处理大宗文件的合成处理.
如果能给出相应的函数或者是程序,或者是解释,加分相送.虽然分不算什么,但是再好的内容也必须通过形式表达.谢谢.[^]
 
procedure TForm1.Button5Click(Sender: TObject);
type
sy=record
nm:string;
n:longint;
end;
var i,j,k:integer;
kk:longint;
kill:array of sy;
ss:string;
tf1,tf2,tf3,tf4:tfilestream;
str1:tstrings;
begin
if listbox1.Items.Count>0 then
begin
if savedialog1.Execute then

try
screen.Cursor:=crHourGlass;
str1:=tstringlist.Create;
setlength(kill,listbox1.Items.Count);
tf1:=tfilestream.Create(savedialog1.FileName,fmCreate);

ss:='';
for j:=1 to 2048 do
begin
ss:=ss+'$';
end;
str1.Text:=ss;
str1.SaveToFile('jill.txt');

tf2:=tfilestream.Create('jill.txt',fmopenread);
str1.Clear;
gauge1.MaxValue:=listbox1.Items.Count-1;
for i:=0 to listbox1.Items.Count-1 do
begin
tf2.Position:=0;
application.ProcessMessages;
tf3:=tfilestream.Create(listbox1.Items.Strings,fmOpenread);
kill.nm:=extractfilename(listbox1.Items.Strings);
kill.n:=tf3.Size;

tf1.CopyFrom(tf3,tf3.Size);
if (tf3.Size mod 2048)<>0 then
begin
tf1.CopyFrom(tf2,(2048-(tf3.Size mod 2048)));
end;
gauge1.Progress:=i;
end;


ss:='';
for k:=1 to 10000 do
begin
kk:=2048*k;
for j:=low(kill) to high(kill) do
begin
ss:=ss+kill[j].nm+':'+inttostr(kk)+':'+inttostr(kill[j].n)+';';
if (kill[j].n mod 2048)<>0 then
begin
kk:=kk+2048*((kill[j].n div 2048) +1);
end
else begin
kk:=kk+kill[j].n
end;
end;

if k*2048>=length(ss) then break;
end;

if (length(ss) mod 2048)<>0 then
begin
for j:=1 to (2048-(length(ss) mod 2048)) do
ss:=ss+'$';
end;

tf1.Position:=0;
str1.Text:=ss;
str1.SaveToStream(tf1);
gauge1.Progress:=0;

finally
tf1.Free;
tf2.Free;
tf3.Free;
str1.Free;
deletefile('jill.txt');
screen.Cursor:=crDefault;
end;

end;
end;
 
我晕昨天忘记把程序COPY了我倒,再来了如题.[:(]
 
重新保存的文件用TMEMORYSTREAM操作吧,应该没有什么问题,我以前合并几十个文件(大约有一百多ZHAO吧)都没有什么问题,如果还不行,我再顶。
 
我需要合成的文件超过int的上界索引,差不多是2G,我需要合成7G~10G的大文件和索引,而且我每次合成200个文件(4M)的时候老是死机,是不是DELPHI不适合做这样的程序我晕,老是卡的不的了结束进程半天都不行,不得不重起.请问,能否有个方式,可以象C一样对内存操作.或者说还有其他的方式.请问.
 
我今天又试了下:把制作索引的部分注释掉,合成比较顺利,但是不注释掉的话合不了多少,我晕,检查了函数和合成少一点的文件倒还可以符合要求,我晕:procedure TForm1.Button5Click(Sender: TObject);
type
sy=record
nm:string;
n:longint;
end;
var i,j,k:integer;
kk:longint;
kill:array of sy;
ss:string;
tf1,tf2,tf3,tf4:tstream;
str1:tstrings;
begin
if listbox1.Items.Count>0 then
begin
if savedialog1.Execute then

try
screen.Cursor:=crHourGlass;
str1:=tstringlist.Create;
setlength(kill,listbox1.Items.Count);
tf1:=tfilestream.Create(savedialog1.FileName,fmCreate);

ss:='';
for j:=1 to 2048 do
begin
ss:=ss+'$';
end;
str1.Text:=ss;
str1.SaveToFile('jill.txt');

tf2:=tfilestream.Create('jill.txt',fmopenread);
str1.Clear;
gauge1.MaxValue:=listbox1.Items.Count-1;
for i:=0 to listbox1.Items.Count-1 do
begin
tf2.Position:=0;
application.ProcessMessages;
tf3:=tfilestream.Create(listbox1.Items.Strings,fmOpenread);
kill.nm:=extractfilename(listbox1.Items.Strings);
kill.n:=tf3.Size;

tf1.CopyFrom(tf3,tf3.Size);
if (tf3.Size mod 2048)<>0 then
begin
tf1.CopyFrom(tf2,(2048-(tf3.Size mod 2048)));
end;
gauge1.Progress:=i;
end;


{ ss:=''
//注释掉的 这难道是问题所在吐血
for k:=1 to 1048575 do
begin
kk:=2048*k;
for j:=low(kill) to high(kill) do
begin
ss:=ss+kill[j].nm+':'+inttostr(kk)+':'+inttostr(kill[j].n)+';';
if (kill[j].n mod 2048)<>0 then
begin
kk:=kk+2048*((kill[j].n div 2048) +1);
end
else begin
kk:=kk+kill[j].n
end;
end;

if k*2048>=length(ss) then break;
end;

ss:=trim(ss);
if (length(ss) mod 2048)<>0 then
begin
for j:=1 to (2048-(length(ss) mod 2048)) do
ss:=ss+'$';
end;

str1.Text:=ss;
tf1.Position:=0;
str1.SaveToStream(tf1)
}
gauge1.Progress:=0;

finally
tf1.Free;
tf2.Free;
tf3.Free;
deletefile('jill.txt');
screen.Cursor:=crDefault;
end;

end;
end;
 
to _Murray,:我按你的要求改了,我晕,合成的时候说'读取流出错误'
程序如下:
procedure TForm1.Button5Click(Sender: TObject);
type
sy=record
nm:string;
n:longint;
end;
var i,j,k:integer;
kk:longint;
kill:array of sy;
ss:string;
tf1,tf2,tf3,tf4:tstream;
str1:tstrings;
begin
if listbox1.Items.Count>0 then
begin
if savedialog1.Execute then

try
screen.Cursor:=crHourGlass;
str1:=tstringlist.Create;
setlength(kill,listbox1.Items.Count);
tf1:=tfilestream.Create(savedialog1.FileName,fmCreate);
tf4:=tmemorystream.Create;
ss:='';
for j:=1 to 2048 do
begin
ss:=ss+'$';
end;
str1.Text:=ss;
str1.SaveToFile('jill.txt');

tf2:=tfilestream.Create('jill.txt',fmopenread);
str1.Clear;
gauge1.MaxValue:=listbox1.Items.Count-1;
for i:=0 to listbox1.Items.Count-1 do
begin
tf2.Position:=0;
application.ProcessMessages;
tf3:=tfilestream.Create(listbox1.Items.Strings,fmOpenread);
kill.nm:=extractfilename(listbox1.Items.Strings);
kill.n:=tf3.Size;

tf4.CopyFrom(tf3,tf3.Size);
if (tf3.Size mod 2048)<>0 then
begin
tf4.CopyFrom(tf2,(2048-(tf3.Size mod 2048)));
end;
gauge1.Progress:=i;
end;


ss:='';
for k:=1 to 1048575 do
begin
kk:=2048*k;
for j:=low(kill) to high(kill) do
begin
ss:=ss+kill[j].nm+':'+inttostr(kk)+':'+inttostr(kill[j].n)+';';
if (kill[j].n mod 2048)<>0 then
begin
kk:=kk+2048*((kill[j].n div 2048) +1);
end
else begin
kk:=kk+kill[j].n
end;
end;

if k*2048>=length(ss) then break;
end;

ss:=trim(ss);
if (length(ss) mod 2048)<>0 then
begin
for j:=1 to (2048-(length(ss) mod 2048)) do
ss:=ss+'$';
end;

str1.Text:=ss;
tf1.Position:=0;
str1.SaveToStream(tf1);
tf1.CopyFrom(tf4,tf4.Size);
gauge1.Progress:=0;

finally
tf1.Free;
tf2.Free;
tf3.Free;
tf4.Free;
str1.Free;
deletefile('jill.txt');
screen.Cursor:=crDefault;
end;

end;
end;
不知道有没更好的解决方案>[:(]
 
我找找以前做的一个程序先。可以发你看看,是一个合并自解压的程序,不过没有合并过你你说的那么大的文件。
 
你可以看看jingtao兄写的一个关于流操作的文章不错.
 
看了你的程序 ,我用进度条加在你后面的循环下,发现你的循环是差不多个死循环所以建议你把循环改成可以控制的,基本上你的程序 可以改成如下:测试通过:
procedure TForm1.Button5Click(Sender: TObject);
type
sy=record
nm:string;
n:longint;
end;
var i,j,k:integer;
kk:longint;
kill:array of sy;
ss:string;
tf1,tf2,tf3,tf4:tstream;
str1:tstrings;
begin
if listbox1.Items.Count>0 then
begin
if savedialog1.Execute then

try
screen.Cursor:=crHourGlass;
str1:=tstringlist.Create;
setlength(kill,listbox1.Items.Count);
tf1:=tfilestream.Create('jjjjj.txt',fmCreate);

ss:='';
for j:=1 to 2048 do
begin
ss:=ss+'$';
end;
str1.Text:=ss;
str1.SaveToFile('jill.txt');

tf2:=tfilestream.Create('jill.txt',fmopenread);
str1.Clear;
gauge1.MaxValue:=listbox1.Items.Count-1;
for i:=0 to listbox1.Items.Count-1 do
begin
kill.nm:=extractfilename(listbox1.Items.Strings);

tf2.Position:=0;
tf3:=tfilestream.Create(listbox1.Items.Strings,fmOpenread);

kill.n:=tf3.Size;

tf1.Seek(0,soFromEnd);
tf1.CopyFrom(tf3,0);
if (tf3.Size mod 2048)<>0 then
begin
tf1.CopyFrom(tf2,(2048-(tf3.Size mod 2048)));
end;
gauge1.Progress:=i;
end;
gauge1.Progress:=0;

application.ProcessMessages;
//索引制作
if ((high(kill)+1)*30 mod 2048)<>0 then
begin
k:=(high(kill)+1)*28 div 2048+1 ;
end
else begin
k:=(high(kill)+1)*30 div 2048;
end;
kk:=2048*k;
gauge1.MaxValue:=high(kill);
ss:='';
for j:=low(kill) to high(kill) do
begin
ss:=ss+kill[j].nm+':'+inttostr(kk)+':'+inttostr(kill[j].n)+';';
gauge1.Progress:=j;
if (kill[j].n mod 2048)<>0 then
begin
kk:=kk+2048*((kill[j].n div 2048) +1);
end
else begin
kk:=kk+kill[j].n
end;
end;


gauge1.Progress:=0;
ss:=trim(ss);
if (length(ss) mod 2048)<>0 then
begin
for j:=1 to (2048-(length(ss) mod 2048)) do
ss:=ss+'$';
end;
str1.Clear;
str1.Text:=ss;

tf4:=tfilestream.Create(savedialog1.FileName,fmCreate);
tf4.Seek(0,soFromBeginning);
str1.SaveToStream(tf4);
tf4.Seek(-2,sofromend);
tf4.CopyFrom(tf1,0);

finally
tf1.Free;
tf2.Free;
tf3.Free;
tf4.Free;
str1.Free;
deletefile('jjjjj.txt');
deletefile('jill.txt');
screen.Cursor:=crDefault;
end;

end;
end;
合成文件大的再搜索到文件头,系统冒了几个寄存器了 所以很容易出错,还不如自己COPY.你再看看
 
[:(]TO Murray, 我的邮箱是jj830104@163.com能发给我看看吗?.[:D]jingtao兄写的文章我没找的哦[:(]
 
waderlym给的程序差不多可以了 应该是循环的问题 谢谢你们[:D]
 
后退
顶部