求助:有没有这样的一次性写入文件函数?(200分)

  • 主题发起人 主题发起人 sxwy
  • 开始时间 开始时间
S

sxwy

Unregistered / Unconfirmed
GUEST, unregistred user!
现在有一个很大的字节数组,想将这些数据写入到一个文件,过程如下:
var
L:integer;
fs : file of byte;//文件类型
tempdata :array of byte;//文件数据
begin:
setlength(tempdata,50000);//要写入的数据个数
assignfile(fs,'c:/aaa.dat');//关联文件
rewrite(fs);
for L := 0 to high(tempdata) do
begin
write(fs,tempdata[L]);//主要是这个过程耗去了很长的时间
end;
closefile(fs);
end;

以上过程,有没有更简单的方式,能将这个tempdata数组一次性写入FS文件呢.高分请朋友们真诚相助.感谢不尽......
 
代码:
procedure TForm1.Button2Click(Sender: TObject);
var
  Target : TFileStream;
  tempdata : array[0..25] of byte ;
  i :integer ;
begin
 // SetLength(tempdata,26);//要写入的数据个数
  for i := 0 to 25 do
   tempdata[i] := i + 65 ;

  Target := TFileStream.Create('c:/bbb.dat', fmOpenWrite or fmCreate);
  try
    Target.WriteBuffer(tempdata, 25);
  finally
    Target.Free;
  end;

end;
 
写到 memorystream,然后保存到 file ,速度最快
 
procedure TForm1.Button1Click(Sender: TObject);
var
Target : TFileStream;
tempdata : array of byte ;
i :integer ;
pTemp:Pointer;
begin
SetLength(tempdata,26);//要写入的数据个数
for i := 0 to 25 do
tempdata := i + 65 ;
ptemp := @tempdata[0];

Target := TFileStream.Create('c:/bbb.dat', fmOpenWrite or fmCreate);
try
Target.WriteBuffer(ptemp^, 25);
finally
Target.Free;
end;

end;
 
var
L:integer;
fs : file of byte;//文件类型
tempdata :array[0..49999] of byte;//文件数据
begin:
//setlength(tempdata,50000);//要写入的数据个数
assignfile(fs,'c:/aaa.dat');//关联文件
rewrite(fs);
blockwrite(fs,tempdata,50000);
closefile(fs);
end;
 
没有什么好的算法,就用线程做,避免了卡界面
 
如果只是这样的话可以考滤使用内存映射文件
绕过文件函数
直接写入文件
 
write 和 writebuffer 效率很低,所以要减少它的调用频率效率自然就提高了。

const
block = 1024; //block的值可以根据需要自行设定
var
i:integer;
fs : TFileStream;//文件类型
tempdata :array of byte;//文件数据
begin:
setlength(tempdata,50000);//要写入的数据个数
fs := TFileStream.Create('c:/aaa.dat',fmCreate or fmOpenWrite);
try
for i:= 0 to (Length(tempdata) div block) - 1 do
begin
fs.write(tempdata[i * block], block);
end;
fs.write((tempdata[i * block], Length(tempdata) mod block););
finally
FreeAndNil(fs);
end;
end;
 
多谢各位相助.祝大家新年事事顺心.
现在的速度有了很大的提高.但是还有一个问题想得到你们的帮助
问题是这样的:
我第一次将10000个字节写入"c:/123.dat"后.文件暂时存在电脑上.
但是以后每次要追加10000个字节.在这种情况下,可否直接往123.DAT上追加而不要将123.DAT读入再追加?

我现在是先用流读入123.DAT的内容,然后在流里面追加10000个字节.再将流保存为123.dat.
还是感到很慢,因为当文件越来越大时,流的读入时间和保存时间是个很大的问题.


以上请各位再帮我一下.多谢了.
 
追加很简单,
把文件指针移到最后,然后write就行了
 
追加不能用Filestream
要用fileopen后,用filewrite写在文件尾处。
 
写成两个文件,然后调用DOS命令 COPY 1.DATA+2.DATA 1.DATA 合成一个文件,COPY也是追加到后面
 
楼上的方法不好,还是我用的方法
 
哪种方式快就用哪种.多谢各位相助.
 
to 我爱PASCAL
怎么不好,写成文件你们是最快的,合成文件用系统自带的功能难道速度会不快,
 
我在C盘已有123.DAT的情况下,每执行以下一次过程,发现123.DAT文件并没有被变大,也就是说,每执行一次后,数据并没有被追加到123.DAT文件后.倒底是哪里不对呢,请各位看一下.谢谢了.
Var
TempByte : Array[0..100000] of byte;
TempHandle: Thandle;
begin
TempHandle := fileopen('C:/ee.dat',fmOpenReadWrite);
filewrite(TempHandle,TempByte[0],High(TempByte) + 1);
end;
 
呵呵 ,再一个seek就可以了。
const filename = 'c:/bbb.dat';

procedure TForm2.Button1Click(Sender: TObject);
var
Target : TFileStream;
tempdata : array[0..25] of byte ;
i :integer ;
begin
for i := 0 to 25 do
tempdata := i + 65 ;
if FileExists(filename) then
begin
Target := TFileStream.Create(filename, fmOpenWrite ) ;
Target.Seek(0, soFromEnd); //指针定位到文件尾部
end
else
Target := TFileStream.Create(filename, fmCreate or fmOpenWrite ) ;
try
Target.Write(tempdata, 26);
finally
Target.Free;
end;

end;

这个过程,执行一次就在'c:/bbb.dat'中增加A到Z共26个字符。这回应该满足了吧
 
看下rewrite 和 append
 
FileSeek(FileHandle, 0, 1);到文件尾
然后filewrite
 
多谢各位相助:
对比了上面的两种方式.张辉明的过程在文件越来越大时(100M以上),过程会变得越来越慢.
我爱PASCAL的过程用FILESEEK(FILEHANDLE,0,1)不会移动到文件尾,而要如下才行:
var tempbyte[0..10000] of byte ;
for i := 0 to 1000 do
begin
TempHandle := fileopen('C:/ee.dat',fmOpenReadWrite);
fileseek(filehandle,i * high(tempbyte),0);才能移动到文件尾.
filewrite(TempHandle,TempByte[0],High(TempByte) + 1);
fileclose(filehandle);//加入关闭过程
end;
请问我爱PASCAL,以上过程如何得到每次打开的FILEHANDLE的文件句柄的最大字节数呢,只有得到这个最大数,才能追加成功.
 
后退
顶部