|
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"ファイル分割と結合"
みなさんこんちわ、十兵衛です。
サイズの大きなファイルを分割し、その一部(先頭)を自作プログラムに結合させ、
実行時に分割されたファイルを結合し元のファイルを組み立てます。
尚、このプログラムはnifty:FDELPHI LIB16 No47に登録されているもののソース
コードです。実行時のダイアログ表示がおかしくなる不具合があります(^^;
実行検証はNT4.0とWIN95です。それ以外の環境では動作させたことがありません。
unit MorSep1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls;
type
//データ管理レコード宣言
//ExeSize 自分自身の実行ファイルサイズ
//DataSize 結合対象のデータファイルサイズ
//DataName 結合対象のデータ名
//FileCnt 分割されたファイル数
TFileRec = packed record
ExeSize,DataSize:Integer;
DataName:string[128];
FileCnt:Integer;
end;
TForm1 = class(TForm)
ProgressBar1: TProgressBar;
OpenDialog1: TOpenDialog;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private 宣言 }
FFlg:Boolean;
FStr1,FStr2:TMemoryStream;
procedure RecRead(var ARec:TFileRec);
procedure FileSeparate(AFileName:TFileName);
procedure FileConcat;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
const
CFileSize:Integer = 1000000;
implementation
{$R *.DFM}
procedure TForm1.RecRead(var ARec: TFileRec);
begin
FStr1.Position := FStr1.Size-SizeOf(ARec);
FStr1.ReadBuffer(ARec,SizeOf(ARec));
FStr1.Position := FStr1.Size-(ARec.DataSize+SizeOf(ARec));
FStr2.CopyFrom(FStr1,ARec.DataSize);
end;
procedure TForm1.FileConcat;
var
FRec:TFileRec;
FFileName:string;
IDX:Integer;
FStr:TMemoryStream;
begin
FStr := TMemoryStream.Create;
try
RecRead(FRec);
if MessageDlg('「'+FRec.DataName+'」を復元します'+
#13#10+'よろしいですか',
mtInformation,mbOKCancel,0) <> mrOK then Exit;
Label2.Caption := FRec.DataName;
ProgressBar1.Step := ProgressBar1.Max div FRec.FileCnt;
for IDX := 1 to FRec.FileCnt-1 do begin
FFileName := ChangeFileExt(Application.ExeName,'');
FFileName := Copy(FFileName,1,Length(FFileName)-3);
FFileName := FFileName + Format('%.3d',[IDX])+'.Dat';
if not FileExists(FFileName) then begin
ShowMessage('ファイルがありません'+#13#10+
ExtractFileName(FFileName));
Break;
end;
Label4.Caption := ExtractFileName(FFileName);
FStr.Clear;
FStr.LoadFromFile(FFileName);
FStr.Position := 0;
FStr2.Position := FStr2.Size;
FStr2.CopyFrom(FStr,FStr.Size);
ProgressBar1.StepIt;
Application.ProcessMessages;
end;
ProgressBar1.Position := ProgressBar1.Max;
FStr2.SaveToFile(ExtractFilePath(Application.ExeName)+
FRec.DataName);
ShowMessage('ファイルの結合が終了しました');
finally
FStr.Free;
Application.Terminate;
end;
end;
procedure TForm1.FileSeparate(AFileName: TFileName);
var
FStr:TFileStream;
FRec:TFileRec;
IDX,Cnt:Integer;
begin
FStr := TFileStream.Create(AFileName,fmOpenRead);
try
FRec.ExeSize := FStr1.Size;
FRec.DataName := ExtractFileName(AFileName);
FRec.DataSize :=
CFileSize - (FRec.ExeSize + SizeOf(FRec));
Cnt := ((FStr.Size-FRec.DataSize) div CFileSize) + 1;
if ((FStr.Size-FRec.DataSize) mod CFileSize) > 0 then
Inc(Cnt);
Application.ProcessMessages;
FRec.FileCnt := Cnt;
FStr1.Position := FStr1.Size;
FStr.Position := 0;
FStr1.CopyFrom(FStr,FRec.DataSize);
FStr1.WriteBuffer(FRec,SizeOf(FRec));
FStr1.SaveToFile(ChangeFileExt(AFileName,'')+'000'+'.exe');
ProgressBar1.Step := ProgressBar1.Max div FRec.FileCnt;
for IDX := 1 to Cnt-1 do begin
FStr2.Clear;
if (FStr.Size-FStr.Position) > (CFileSize) then begin
FStr2.CopyFrom(FStr,CFileSize);
end else begin
FStr2.CopyFrom(FStr,FStr.Size-FStr.Position);
end;
FStr2.SaveToFile(ChangeFileExt(AFileName,'')+
Format('%.3d',[IDX])+'.Dat');
ProgressBar1.StepIt;
Application.ProcessMessages;
end;
ProgressBar1.Position := ProgressBar1.Max;
ShowMessage('ファイルの分割が終了しました');
finally
FStr.Free;
Application.Terminate;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
FStr:string;
begin
//
FStr1 := TMemoryStream.Create;
FStr2 := TMemoryStream.Create;
FStr1.LoadFromFile(Application.ExeName);
//
FStr := ChangeFileExt(ExtractFileName(
Application.ExeName),'');
FStr := Copy(FStr,Length(FStr)-2,3);
FFlg := AnsiCompareText(FStr,'000') = 0;
if FFlg then begin
Label1.Caption := 'ファイルを結合中';
Label2.Caption := '';
Label3.Caption := '処理ファイル名';
Label4.Caption := '';
end else begin
Button1.Visible := True;
Label2.Caption := 'ファイルを選択してください';
Label3.Visible := False;
Label4.Visible := False;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FStr1.Free;
FStr2.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
OpenDialog1.FileName := '';
if not OpenDialog1.Execute then begin
Label2.Caption := 'ファイルを選択してください';
Exit;
end;
if MessageDlg('選択された「'+ExtractFileName(
OpenDialog1.FileName)+
'」を分割します'+#13#10+'よろしいですか',
mtInformation,mbOKCancel,0) = mrOK then begin
CFileSize := StrToIntDef(InputBox('ファイルサイズ',
'ファイルサイズを入力してください'+#13#10+
'標準で'+IntToStr(CFileSize)+'Byteです',
IntToStr(CFileSize)),CFileSize);
Label2.Caption := ExtractFileName(OpenDialog1.FileName);
Self.FileSeparate(OpenDialog1.FileName);
Application.Terminate;
end else Label2.Caption := 'ファイルを選択してください';
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
if not FFlg then Exit;
Self.FileConcat;
end;
end.
ではでは(^^)/
Original document by 十兵衛 氏 ID:(BZT01311)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|