|
Вопрос # 63/ вопрос открыт / |
|
здраствуте
прочитал я статю - Копирование файлов - Выпуск #43 (08 марта 2006 г.) и вот сечас все мучаюсь как переделать код чтоб не скопировать файл - а чтоб соединить два файла.
за ранее благодарен
Приложение: Переключить в обычный режим-
- type
-
-
- procedure FastFileCopy(Const InfileName, OutFileName: String; CallBack: TCallBack);
-
- type
- PBuffer = ^TBuffer;
- TBuffer = array [1..BufSize] of Byte;
- var
- Size : integer;
- Buffer : PBuffer;
- infile, outfile : File;
- SizeDone,SizeFile: Longint;
- begin
- if (InFileName <> OutFileName) then
- begin
- buffer := Nil;
- AssignFile(infile, InFileName);
- System.Reset(infile, 1);
- try
- SizeFile := FileSize(infile);
- AssignFile(outfile, OutFileName);
- System.Rewrite(outfile, 1);
- try
- SizeDone := 0; New(Buffer);
- repeat
- BlockRead(infile, Buffer^, BufSize, Size);
- Inc(SizeDone, Size);
- CallBack(SizeDone, SizeFile);
- BlockWrite(outfile,Buffer^, Size)
- until Size < BufSize;
- FileSetDate(TFileRec(outfile).Handle,
- FileGetDate(TFileRec(infile).Handle));
- finally
- if Buffer <> Nil then Dispose(Buffer);
- System.close(outfile)
- end;
- finally
- System.close(infile);
- end;
- end else
- Raise EInOutError.Create('File cannot be copied into itself');
- end;
-
-
- procedure FileCopy(Const SourceFileName, TargetFileName: String);
- var
- S,T : TFileStream;
- begin
- S := TFileStream.Create(sourcefilename, fmOpenRead );
- try
- T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate);
- try
- T.CopyFrom(S, S.Size ) ;
- FileSetDate(T.Handle, FileGetDate(S.Handle));
- finally
- T.Free;
- end;
- finally
- S.Free;
- end;
- end;
-
-
- uses LZExpand;
-
- procedure CopyFile(FromFileName, ToFileName : string);
- var
- FromFile, ToFile: File;
- begin
- AssignFile(FromFile, FromFileName);
- AssignFile(ToFile, ToFileName);
- Reset(FromFile);
- try
- Rewrite(ToFile);
- try
- if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle)<0 then
- raise Exception.Create('Error using LZCopy')
- finally
- CloseFile(ToFile);
- end;
- finally
- CloseFile(FromFile);
- end;
- end;
-
 |
Вопрос задал: Oleg (статус: Посетитель)
Вопрос отправлен: 26 июня 2006, 18:48
Состояние вопроса: открыт, ответов: 4.
|
Ответ #1. Отвечает эксперт: Помфюк Владимир Степанович
Здравствуйте, Oleg!
приблизительно так:
1. Копирование методом Pascal.
type
TCallBack=procedure (Position,Size:Longint); {Для индикации процесса копирования}
procedure FastFileCopy(Const InfileName1,InfileName2, OutFileName: String; CallBack: TCallBack);
Const BufSize = 3*4*4096; { 48Kbytes дает прекрасный результат }
type
PBuffer = ^TBuffer;
TBuffer = array [1..BufSize] of Byte;
var
Size : integer;
Buffer : PBuffer;
infile1, infile2, outfile : File;
SizeDone,SizeFile: Longint;
begin
if (InFileName1 <> OutFileName)and(InFileName2 <> OutFileName) then
begin
buffer := Nil;
AssignFile(infile1, InFileName1);
System.Reset(infile1, 1);
AssignFile(infile1, InFileName2);
System.Reset(infile1, 1);
try
AssignFile(outfile, OutFileName);
System.Rewrite(outfile, 1);
try
New(Buffer);
SizeFile := FileSize(infile1);
SizeDone := 0;
repeat
BlockRead(infile1, Buffer^, BufSize, Size);
Inc(SizeDone, Size);
CallBack(SizeDone, SizeFile);
BlockWrite(outfile,Buffer^, Size)
until Size < BufSize;
FileSetDate(TFileRec(outfile).Handle,
FileGetDate(TFileRec(infile1).Handle));
SizeFile := FileSize(infile2);
SizeDone := 0;
repeat
BlockRead(infile2, Buffer^, BufSize, Size);
Inc(SizeDone, Size);
CallBack(SizeDone, SizeFile);
BlockWrite(outfile,Buffer^, Size)
until Size < BufSize;
finally
if Buffer <> Nil then Dispose(Buffer);
System.close(outfile)
end;
finally
System.close(infile1);
System.close(infile2);
end;
end else
Raise EInOutError.Create('File cannot be copied into itself');
end;
 |
Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент)
Время отправки: 26 июня 2006, 18:59
Оценка за ответ: 2
Комментарий к оценке: не работает :( пустой файл получается
да и хотелось чтоб Файл1 приплюсовалсья к Файлу2
|
Ответ #2. Отвечает эксперт: min@y™
Предлагаю использовать 2 экземпляра TFileStream. Могу, если надо, написать пример. Будет просто и изящно. Но сейчас времени нету, пиши в мыло или сюда на форум.
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 27 июня 2006, 08:17
|
Ответ #3. Отвечает эксперт: bruder
Здравствуйте, Oleg!
Сам пользуюсь этим: (один минус-получившийся файл использовать не удасться, его нужно будет сначало "распаковать".)
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Forms, Classes, Controls, StdCtrls;
-
- type
- TForm1 = class(TForm)
- Button1: TButton;
- procedure Button1Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
- Procedure AddToStream ( Source , Dest : TStream );
- var
- Size : Integer ;
- begin
- Source.position := 0 ;
- Size := Source.Size ;
- Dest.Write(Size,SizeOf(Integer));
- Dest.CopyFrom(Source,Source.size);
- end;
-
- Procedure ThisISHowIPutFilesIn;
- var
- ABigFileStream, SomeSmallFiles : TMemoryStream ;
- begin
- ABigFileStream := TMemoryStream.Create ;
- try
- SomeSmallFiles := TMemoryStream.Create ;
- try
- SomeSmallFiles.LoadFromFile('1.exe');
- AddToStream(SomeSmallFiles,ABigFileStream);
- SomeSmallFiles.LoadFromFile('2.exe');
- AddToStream(SomeSmallFiles,ABigFileStream);
-
- finally
- SomeSmallFiles.Free ;
- end;
- ABigFileStream.SaveToFile('OutFile')
- finally
- ABigFileStream.free ;
- end;
- end;
-
- procedure TForm1.Button1Click(Sender: TObject);
- begin
- ThisISHowIPutFilesIn;
- end;
-
- end.
-
- Procedure GetFromStream ( Source , Dest : TStream ; Index : Integer );
- Var
- Size , I : Integer ;
- begin
- Source.Position := 0 ;
- For i := 0 to index-1 do
- begin
- Source.Read(Size,SizeOf(Integer));
- Source.Position := Source.Position + Size ;
- end;
- if Source.position = Source.Size then
- Raise EAccessViolation.Create('Index Out Of Bounds') ;
- Source.Read(Size,SizeOf(Integer));
- Dest.Position := 0 ;
- Dest.Size := 0 ;
- Dest.CopyFrom(Source,Size);
- end;
-
- Procedure ThisISHowIGetStufOut;
- var
- ABigFileStream, SomeSmallFiles : TMemoryStream ;
- begin
- ABigFileStream := TMemoryStream.Create ;
- try
- ABigFileStream.LoadFromFile('OutFile');
- SomeSmallFiles := TMemoryStream.Create ;
- try
- GetFromStream(ABigFileStream,SomeSmallFiles,0);
- SomeSmallFiles.SaveToFile('1.exe');
- GetFromStream(ABigFileStream,SomeSmallFiles,1);
- SomeSmallFiles.SaveToFile('2.exe');
- finally
- SomeSmallFiles.Free ;
- end;
- finally
- ABigFileStream.free ;
- end;
- end;
 |
Ответ отправил: bruder (статус: 4-ый класс)
Время отправки: 27 июня 2006, 09:57
|
Ответ #4. Отвечает эксперт: Косолапов Дмитрий Юрьевич
В первом способе вместо Rewrite(outfile, 1) Reset(outfile, 1). Наверное, надо будет еще и спозиционироваться на конце файла (Seek).
Во втором способе вместо T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate) попробуй T := TFileStream.Create(targetfilename, fmOpenReadWrite)
В третьем способе - аналогично первому
Мини-форум вопроса
Всего сообщений: 1; последнее сообщение — 27 июня 2006, 10:41; участников в обсуждении: 1.
|
min@y™ (статус: Доктор наук), 27 июня 2006, 10:41 [#1]:
Вот, написал 100% рабочий пример (отладил):
// Слияние 2х файлов
procedure TForm1.CopyButtonClick(Sender: TObject);
var
FIn, FOut: TFileStream;
InSize1, InSize2, OutSize: Int64;
begin
if (not FileExists(LabeledEdit1.Text)) or (not FileExists(LabeledEdit2.Text))
then begin
Application.MessageBox(PChar('Один из входных файлов не найден.'),
PChar('Облом'),
MB_OK + MB_ICONERROR);
Exit;
end;
try
CopyButton.Enabled:= False;
FOut:= TFileStream.Create(LabeledEdit3.Text, fmCreate or fmShareExclusive);
try
FIn:= TFileStream.Create(LabeledEdit1.Text, fmOpenRead or fmShareExclusive);
try
FOut.CopyFrom(FIn, 0);
finally
InSize1:= FIn.Size;
FIn.Free;
end;
FIn:= TFileStream.Create(LabeledEdit2.Text, fmOpenRead or fmShareExclusive);
try
FOut.CopyFrom(FIn, 0);
finally
InSize2:= FIn.Size;
FIn.Free;
end;
finally
OutSize:= FOut.Size;
FOut.Free;
CopyButton.Enabled:= True;
end;
Application.MessageBox(PChar('Слияние файлов прошло удачно. '#13#10'Размер 1-го файла: '
+ IntToStr(InSize1)
+ ' байт'#13#10'Размер 2-го файла: '
+ IntToStr(InSize2)
+ ' байт'#13#10'Размер выходного файла: '
+ IntToStr(OutSize) + ' байт'#13#10),
PChar(''),
MB_OK + MB_ICONINFORMATION);
except
on E: Exception do
Application.MessageBox(PChar(E.Message),
PChar('Ошибка копирования'),
MB_OK + MB_ICONERROR);
end;
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|