关于文件复制的问题,附代码,请高手帮忙分析错误。(100分)

  • 主题发起人 主题发起人 mat
  • 开始时间 开始时间
M

mat

Unregistered / Unconfirmed
GUEST, unregistred user!
因程序设计的需要,要把比较大的文件分成小的文件块来传递,保存。研究了几天,碰上
一点小麻烦。代码如下。
public
{ Public declarations }
bigfile,smallfile:string;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var m,n:tmemorystream;
i,j:integer;
begin
if bigfile='' then
exit;
m:=tmemorystream.Create;
m.LoadFromFile(bigfile);
{ n:=tmemorystream.Create;
n.SetSize(3276800);
j:=tmemorystream.Create;
j.SetSize(m.size-3276800);
move(m.memory^,n.memory^,3276800);
//m.Position:=32768;
move(m.memory^,j.memory^,m.size-3276800);
n.SaveToFile('c:/001.swf');
j.SaveToFile('c:/002.swf');
m.Free;
n.free;
j.free; }
j:=(m.Size div 32768);
i:=0;
while i<=j do
begin
n:=tmemorystream.Create;
if i=j then
begin
n.SetSize(m.size mod 32768);
move(m.memory^,n.memory^,(m.size mod 32768));
end
else
begin
n.SetSize(32768);
move(m.memory^,n.memory^,32768);
end;
n.SaveToFile('c:'+copy(inttostr(i+1000),2,3)+'.cut');
inc(i);
n.Free;
end;
m.free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var m,n:tmemorystream;
i,j:integer;
begin
m:=tmemorystream.Create;

{ n:=tmemorystream.Create;
j:=tmemorystream.Create;
n.LoadFromFile('c:/001.swf');
j.LoadFromFile('c:/002.swf');
m.SetSize(n.size+j.size);
move(n.memory^,m.memory^,n.size);
move(j.memory^,m.memory^,j.size);
m.SaveToFile('c:/003.swf');
m.free;
n.free;
j.free; }

i:=0;
j:=159;
m.SetSize(5230496);//根据选择的原文件大小而不同
while i<=j do
begin
n:=tmemorystream.Create;
n.LoadFromFile('c:/'+copy(inttostr(i+1000),2,3)+'.cut');
move(n.memory^,m.memory^,n.size);
inc(i);
n.free;
end;
m.SaveToFile('c:/02.swf');
m.Free;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
if OpenDialog1.Execute then
bigfile:=OpenDialog1.FileName;
end;
以上部分的代码均可执行,如果用注释部分的内容,文件将分成两个小的文件,切割合并
均无问题。但当采用非注释部分的时候,文件切割合并以后得到的还原文件无法正常运行。
请高手指点。
 
不是吧,20多票人马来了又走,就没一票人接这笔买卖么。
 
太长了,
我也写了一个文件分割的东西
有原码,你下来看看
http://antic_ant.delphibbs.com
 
to antic_ant
给的地址打不开呀,是不是错了

to all
就没有别的答案了吗
 
你的代码有问题:
过程Move(const Source; var Dest; Count: Integer);的作用是从Source复制Count字节
数据到Dest。 你在Button1Click中的每一次循环都move(m.memory^,n.memory^,32768);
也就是说m.memory中的东西始终是32768字节的数据,你每次都覆盖了它。

所以最好的方法是使用TMemorystream的Read,和Write方法,这时,你甚至不用SetSize来
指定TMemorystream的尺寸。
至于为什么注释中的内容执行正确,那是因为在Button2Click中真正起作用的是
move(j.memory^,m.memory^,j.size);
而前面的move(n.memory^,m.memory^,n.size);所执行的操作被完全覆盖了




 
to ASCII
可能我贴的代码太长了,现在简要描述一下,BUTTON1的功能是将一大的文件分成了两个小
文件,我做这个的时候选择了是一5M的FLASH动画。分割后的小文件保存为001.SWF和002。SWF
BUTTON2的功能是把001。SWF和002.SWF重新组合成一个文件另起名为003.SWF。

另外Move的作用的确是从Source复制Count字节数据到Dest,但是决定复制字节起始位置的是
memorystream.Position属性,执行MOVE过程以后将会使Position指针自动指向复制字节串的
结尾看一下READ函数在VCL中的定义就可以发现其实它也是调用了move过程。另外我觉得问
题应该不是你所说的在BUTTON2注释中move(j.memory^,m.memory^,j.size);
覆盖了move(n.memory^,m.memory^,n.size);所执行的操作。因为J所读出的是原文件的后半部分
而N读出的是文件的前半部分,当执行完这两句以后所得到的M和原先的大文件是一样的。
 
呵呵,刚才试了一下,ASCII兄弟说的是对的,用了READ和WRITE以后确实就解决了问题。
问题应该是出在MOVE以后POSITION没有指向正确的位置。
还有个小问题请教一下,BUTTON1和BUTTON2中注释部分没有用READ和WRITE但也能得到正确
结果是为什么?希望能得到答案.期待,下午结分。
 
接受答案了.
 
SWF文件在网页上浏览的时候,不等文件完全传输完毕就可以正常显示,所以,SWF文件的
前一办也许就能够正常显示。
 
后退
顶部