合并分段存储的文件,十万火急啊!(100分)

  • 主题发起人 主题发起人 偶尔幽默
  • 开始时间 开始时间

偶尔幽默

Unregistered / Unconfirmed
GUEST, unregistred user!
数据库中两张表,表1(文章)和表2(文章内容),表2是以二进制流分段存储的,以32K为分界点,现用流读取分段存储的数据合并成文件,合并后的文件大小是对的,但打开文件是乱码或无法打开。文件的类型有多种,DOC,PPT,PDF等。
大家看下代码有没有问题:
function Tf_main.transEfile(contentId,fileName,pid:string): string;
var
efileTitle,efilePath:string;
a: TFileStream;
b:TMemoryStream;
begin
with self.qry_content do
begin
Close;
SQL.Clear;
SQL.Add(format('select CONTENT,SPLITNO,text from EB_ARTICLE_CONTENT_BB '
+'where ARTICLE_CONTENT_ID =''%s'''
+' order by SPLITNO',[trim(contentid)]));
Open;
efileTitle:= fileName;
efilePath:= ExtractFilePath(ParamStr(0))+'/temp/';
a := TFileStream.Create(efilePath+efileTitle, fmCreate);
First;
while not qry_content.Eof do
begin
try
b:= TMemoryStream.Create;
TBlobField(FieldbyName('content')).SaveToStream(b);
try
b.Position :=0;
a.Seek(0,soFromEnd); //
a.CopyFrom(b,0);
finally
FreeAndNil(b);
end;
except
Break;
end;
qry_content.Next;
end;
end;
end;
 
a.CopyFrom(b,0);
改为
a.writebuffer(b, b.size);

而且应该将b的创建代码放到循环外面
 
我照你说的改了,还是不行啊,把a.Copyfrom(b,0)改为 a.writebuffer(b,b.size)后,执行到a.writebuffer(b,b.size)这里后就报错,说写入错误,我又改为a.writebuffer(b,0)后可以执行过去,可是执行第二次循环时,到TBlobField(FieldbyName('content')).SaveToStream(b)这句就报错了。
大侠们,救救我吧,我快崩溃了。
 
这个东西没有做过。
但我是这样想的,
第一对于每一个保存到数据库中的文件,我想对于文件头等应该有个相关的标识,你应该把它去掉,然后只COPY其中的内容。
第二就是对于b这个内存流,每次在追加到a中后,需要把b给释放掉,然后再去创建,并且对于content这个字段中的内容进行判断是否有值再去SaveToStream。
 
谢谢各位了,感谢两位大侠关注,问题已经解决了,现把解决后的源码贴出来,供以后有需要的哥们参考。解决的方法是在读取时跳过文件头。
function Tf_main.transEfile(contentId,fileName,pid:string): string;
var
efileTitle,efilePath:string;
// a: TFileStream;
// b:TMemoryStream;
f, f2, sz, r: integer;
buf: array[1..1024] of byte;
begin
Try
if TblobField(ADOQuery1.FieldByName('ole_counter')).BlobSize <> 0 then
begin
efileTitle:= fileName;
efilePath:= ExtractFilePath(ParamStr(0))+'/temp/';
TblobField(ADOQuery1.FieldByName('ole_counter')).SaveToFile(efilePath+efileTitle);
end ;

//第二步:导出电子文件,并组合
if contentid <> '' then
begin
with self.qry_content do
begin
Close;
SQL.Clear;
SQL.Add(format('select CONTENT,SPLITNO,text from WEB_ARTICLE_CONTENT_BB '
+'where ARTICLE_CONTENT_ID =''%s'''
+' order by SPLITNO',[trim(contentid)]));
Open;
efileTitle:= fileName;
efilePath:= ExtractFilePath(ParamStr(0))+'/temp/';

f := FileCreate(efilePath+efileTitle);

qry_content.First ;
while not qry_content.Eof do
begin
TBlobField(FieldByName('CONTENT')).SaveToFile('c:/temp'+inttostr(recno));
sz := TBlobField(FieldByName('CONTENT')).BlobSize;
f2 := FileOpen('c:/temp'+inttostr(recno),fmOpenRead);
if recno = 1 then
begin
sz := sz - 11;
FileSeek(f2,12,0);
end else
FileSeek(f2,0,0);

repeat
if sz < sizeof(buf) then
r := sz
else
r := sizeof(buf);
FileRead(f2, buf, r);
FileWrite(f, buf, r);
sz := sz - r;
until sz <= 0;

FileClose(f2);
DeleteFile('c:/temp'+inttostr(recno));
next;
end;
FileClose(f);
end;
end;
问题解决,结贴了。
 
后退
顶部