begin FSFileOpen := TOpenDialog.Create(Application); FSFileOpen.Filename := GetValue; FSFileOpen.Filter := 'All files (*.*)|*.*'; FSFileOpen.Options := FSFileOpen.Options + [ofShowHelp, ofPathMustExist]; FSFileOpen.Title := 'Select a file to split'; try if FSFileOpen.Execute then SetValue(FSFileOpen.Filename); finally FSFileOpen.Free; end; end;function TFSFilenameProperty.GetAttributes: TPropertyAttributes; begin Result := [paDialog, paRevertable]; end;{ TFSSplitFilenameProperty }procedure TFSSplitFilenameProperty.Edit; var FSFileSave: TSaveDialog;begin FSFileSave := TSaveDialog.Create(Application); FSFileSave.Filename := GetValue; FSFileSave.Filter := 'Split files (*.spl)|*.SPL'; FSFileSave.Options := FSFileSave.Options + [ofShowHelp, ofPathMustExist]; FSFileSave.Title := 'Select the first split file (.SPL)'; try if FSFileSave.Execute then SetValue(FSFileSave.Filename); finally FSFileSave.Free; end; end;function TFSSplitFilenameProperty.GetAttributes: TPropertyAttributes; begin Result := [paDialog, paRevertable]; end;{ TFileSplitter }{ Sets the name of the file to split } procedure TFileSplitter.SetFileName(Value: TFileName); begin if Value <> FFileName then begin FFileName := Value; if not FOutDifferent then FSplitFileName := ChangeFileExt(Value, '.SPL'); end; end;
{ Sets the name of the first split file - all other split files will have the same name, with extensions .001, .002, .003 etc. } procedure TFileSplitter.SetSplitFileName(Value: TFileName); begin if Value <> FSplitFileName then begin FSplitFileName := Value; FOutDifferent := True; end; end;{ Sets the maximum size of split files } procedure TFileSplitter.SetSize(Value: LongInt); begin if Value <> FSize then FSize := Value; end;{ Sets the maximum size of the first split file } procedure TFileSplitter.SetReduceFirstSizeBy(Value: LongInt); begin if Value <> FReduceFirstSizeBy then if (FSize - SizeOf(Signature) - Value) > 0 then FReduceFirstSizeBy := Value; end;{ Sets the buffer size } procedure TFileSplitter.SetBufferSize(Value: Integer); begin if Value <> FBufferSize then FBufferSize := Value; end;{ Component constructor... } constructor TFileSplitter.Create(AOwner: TComponent); begin inherited; FFileName := ''; FSplitFileName := FFileName; FOutDifferent := False; FSize := 1457664; FBufferSize := 1457664; FReduceFirstSizeBy := 0; Signature.Copyright := 'TFileSplitter by Jovan Sedlan'; Signature.NumberOfFiles := 0; end;{ EraseFile deletes a file on disk } procedure EraseFile(FN: TFileName); var f: File;begin AssignFile(f, FN); Erase(f); end;{ StrZero returns a string representation of a Number, Len characters long, with leading zeroes } function StrZero(Number: LongInt; Len: Byte): String; var Temp: String;begin Temp := Trim(IntToStr(Number)); Result := StringOfChar('0', Len - Length(Temp)) + Temp; end;{ Split method does the actual work - splits a file into multiple files } procedure TFileSplitter.Split; var i: Integer; Continue: Boolean; FileCount, PercentDone: Integer; sFileName: TFileName; BytesToRead, BytesWritten, BytesRead, BytesStored, LastSplitFileSize: LongInt; TheSize: LongInt;begin if FileExists(FFileName) then begin { Make sure the filename is correct } if FSplitFileName = '' then FSplitFileName := ChangeFileExt(FFileName, '.SPL'); { Prepare for reading from file } FFile := TFileStream.Create(FFileName, fmOpenRead); GetMem(FBuffer, FBufferSize); { Calculate the number of resulting files } FileCount := (FFile.Size + SizeOf(Signature)) div FSize; LastSplitFileSize := (FFile.Size + SizeOf(Signature)) mod FSize; if LastSplitFileSize <> 0 then Inc(FileCount); if (LastSplitFileSize + FReduceFirstSizeBy) > FSize then Inc(FileCount); Signature.NumberOfFiles := FileCount; try { Write resulting file(s) } i := 1; Continue := True; sFileName := FSplitFileName; while (i <= FileCount) do begin if Assigned(FOnNeedDisk) then FOnNeedDisk(Self, i, Signature.NumberOfFiles, Continue); if Continue then begin { Delete the resulting file if it exists } if FileExists(sFileName) then EraseFile(sFileName); FSplitFile := TFileStream.Create(sFileName, fmCreate); BytesWritten := 0; if i = 1 then begin { Put the signature in the first split file } FSplitFile.Write(Signature, SizeOf(Signature)); { Write one file } BytesToRead := FBufferSize; if BytesToRead > FSize - FReduceFirstSizeBy then BytesToRead := FSize - FReduceFirstSizeBy; BytesToRead := BytesToRead - SizeOf(Signature); BytesWritten := SizeOf(Signature); { Real size of the split file } TheSize := FSize - FReduceFirstSizeBy; end else begin { Write one file } BytesToRead := FBufferSize; if BytesToRead > FSize then BytesToRead := FSize; { Real size of the split file } TheSize := FSize; end; while BytesWritten < TheSize do begin if BytesToRead > TheSize - BytesWritten then BytesToRead := TheSize - BytesWritten; BytesRead := FFile.Read(FBuffer^, BytesToRead); BytesStored := FSplitFile.Write(FBuffer^, BytesRead); Inc(BytesWritten, BytesStored); { Call OnProgress event } if Assigned(FOnProgress) then begin if i = FileCount then PercentDone := (BytesWritten * 100) div LastSplitFileSize else PercentDone := (BytesWritten * 100) div TheSize; FOnProgress(Self, PercentDone); end; if FFile.Position = FFile.Size then Break; end; FSplitFile.Free; sFileName := ChangeFileExt(sFileName, '.' + StrZero(i, 3)); Inc(i); end; end; finally { Clean up } FreeMem(FBuffer); FFile.Free; end; end else raise EFileError.Create('Input file ''' + FFileName + ''' does not exist.'); end;
{ Method UnSplit creates the original file from the split files. Name and extension of the original file must be set in FileName property } procedure TFileSplitter.UnSplit; var i: Integer; Continue: Boolean; sFileName: TFileName; BytesRead, TotalRead: LongInt;begin if FileExists(FSplitFileName) then begin { Make sure the filename is correct } if FFileName = '' then FFileName := ChangeFileExt(FSplitFileName, '.XXX'); { Delete the resulting file if it exists } if FileExists(FFileName) then EraseFile(FFileName); { Prepare for writing to file } FFile := TFileStream.Create(FFileName, fmCreate); GetMem(FBuffer, FBufferSize); try i := 0; sFileName := FSplitFileName; { Read files one by one and write to resulting file } Continue := True; Signature.NumberOfFiles := 0; while Continue do begin if Assigned(FOnNeedDisk) then FOnNeedDisk(Self, i + 1, Signature.NumberOfFiles, Continue); if Continue then begin if FileExists(sFileName) then begin try FSplitFile := TFileStream.Create(sFileName, fmOpenRead); { Read the signature from the first split file } if i = 0 then FSplitFile.Read(Signature, SizeOf(Signature)); TotalRead := 0; while FSplitFile.Size <> FSplitFile.Position do begin BytesRead := FSplitFile.Read(FBuffer^, FBufferSize); FFile.Write(FBuffer^, BytesRead); TotalRead := TotalRead + BytesRead; { Call OnProgress event } if Assigned(FOnProgress) then FOnProgress(Self, (TotalRead * 100) div FSplitFile.Size); end; finally FSplitFile.Free; end; Inc(i); sFileName := ChangeFileExt(sFileName, '.' + StrZero(i, 3)); end else Continue := False; end; end; finally FreeMem(FBuffer); FFile.Free; end; end else raise EFileError.Create('Input file ''' + FSplitFileName + ''' does not exist.'); end;{ Register component and property editors } procedure Register; begin RegisterComponents('SEDLAN A.D.', [TFileSplitter]); RegisterPropertyEditor(TypeInfo(TFileName), TFileSplitter, 'FileName', TFSFileNameProperty); RegisterPropertyEditor(TypeInfo(TFileName), TFileSplitter, 'SplitFileName', TFSSplitFileNameProperty); end;end.
没有必要用二进制标记.按字节处理就可以了.你是要把文件按bit拆分吗?那样才回用到二进制处理的方法
例 unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject); var F:TFileStream; Buffer: Array of Char; Buf: PChar; F1:TFileStream; begin //把1.bmp分开 F:=TFileStream.Create('E:\1.bmp',fmOPenRead); Setlength(Buffer,F.size); Buf:=@Buffer; F.Position:=0; F.Read(Buf,F.Size); F1:=TFileStream.Create('E:\1_1.bmp',fmCreate); F1.Write(Buf,100); F1.Free; F1:=TFileStream.Create('E:\1_2.bmp',fmCreate); Buf:=Buf+100; F1.Write(Buf,F.Size-100); F1.Free; F.Free; end;procedure TForm1.Button2Click(Sender: TObject); var F:TFileStream; F1: TFileStream; Buffer: Array of Char; buf:PChar; begin F:=TFileStream.Create('E:\H1.bmp',FmCreate); F1:=TFileStream.Create('E:\1_1.bmp',fmOpenRead); buf:=@buffer; if length(buffer)<F1.Size then SetLength(Buffer,f1.size); F1.Read(buf,F1.Size); F.Write(buf,F1.Size); F1.Free; F1:=TFileStream.Create('E:\1_2.bmp',fmOpenRead); if length(buffer)<=F1.Size then SetLength(Buffer,f1.size); F1.Read(buf,F1.Size); F.Write(buf,F1.Size); F1.free; F.Free; end;end.
unit FileSplitter;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DsgnIntf;type
TSignature = record
Copyright: array [1..29] of Char;
NumberOfFiles: Word;
end;
EFileError = class(Exception); TNeedDiskEvent = procedure(Sender: TObject; DiskID, NumOfDisks: Word; var Continue: Boolean) of object;
TProgressEvent = procedure(Sender: TObject; PercentDone: Word) of object; TFSFilenameProperty = class(TStringProperty)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end; TFSSplitFilenameProperty = class(TStringProperty)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end; TFileSplitter = class(TComponent)
private
FFileName: TFileName;
FSize: LongInt;
FSplitFileName: TFileName;
FOutDifferent: Boolean;
FFile: TFileStream;
FSplitFile: TFileStream;
FBuffer: Pointer;
FBufferSize: Integer;
FReduceFirstSizeBy: LongInt;
Signature: TSignature; FOnNeedDisk: TNeedDiskEvent;
FOnProgress: TProgressEvent; procedure SetFileName(Value: TFileName);
procedure SetSize(Value: LongInt);
procedure SetReduceFirstSizeBy(Value: LongInt);
procedure SetBufferSize(Value: Integer);
procedure SetSplitFileName(Value: TFileName);
protected
public
constructor Create(AOwner: TComponent); override;
procedure Split;
procedure UnSplit;
published
property FileName: TFileName read FFileName write SetFileName;
property SplitFileName: TFileName read FSplitFileName write SetSplitFileName;
property Size: LongInt read FSize write SetSize;
property BufferSize: Integer read FBufferSize write SetBufferSize;
property ReduceFirstSizeBy: LongInt read FReduceFirstSizeBy write SetReduceFirstSizeBy; property OnNeedDisk: TNeedDiskEvent read FOnNeedDisk write FOnNeedDisk;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
end;procedure Register;implementation{ TFSFilenameProperty }procedure TFSFilenameProperty.Edit;
var
FSFileOpen: TOpenDialog;
begin
FSFileOpen := TOpenDialog.Create(Application);
FSFileOpen.Filename := GetValue;
FSFileOpen.Filter := 'All files (*.*)|*.*';
FSFileOpen.Options := FSFileOpen.Options + [ofShowHelp, ofPathMustExist];
FSFileOpen.Title := 'Select a file to split';
try
if FSFileOpen.Execute then
SetValue(FSFileOpen.Filename);
finally
FSFileOpen.Free;
end;
end;function TFSFilenameProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog, paRevertable];
end;{ TFSSplitFilenameProperty }procedure TFSSplitFilenameProperty.Edit;
var
FSFileSave: TSaveDialog;begin
FSFileSave := TSaveDialog.Create(Application);
FSFileSave.Filename := GetValue;
FSFileSave.Filter := 'Split files (*.spl)|*.SPL';
FSFileSave.Options := FSFileSave.Options + [ofShowHelp, ofPathMustExist];
FSFileSave.Title := 'Select the first split file (.SPL)';
try
if FSFileSave.Execute then
SetValue(FSFileSave.Filename);
finally
FSFileSave.Free;
end;
end;function TFSSplitFilenameProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog, paRevertable];
end;{ TFileSplitter }{ Sets the name of the file to split }
procedure TFileSplitter.SetFileName(Value: TFileName);
begin
if Value <> FFileName then
begin
FFileName := Value;
if not FOutDifferent then
FSplitFileName := ChangeFileExt(Value, '.SPL');
end;
end;
have the same name, with extensions .001, .002, .003 etc. }
procedure TFileSplitter.SetSplitFileName(Value: TFileName);
begin
if Value <> FSplitFileName then
begin
FSplitFileName := Value;
FOutDifferent := True;
end;
end;{ Sets the maximum size of split files }
procedure TFileSplitter.SetSize(Value: LongInt);
begin
if Value <> FSize then
FSize := Value;
end;{ Sets the maximum size of the first split file }
procedure TFileSplitter.SetReduceFirstSizeBy(Value: LongInt);
begin
if Value <> FReduceFirstSizeBy then
if (FSize - SizeOf(Signature) - Value) > 0 then
FReduceFirstSizeBy := Value;
end;{ Sets the buffer size }
procedure TFileSplitter.SetBufferSize(Value: Integer);
begin
if Value <> FBufferSize then
FBufferSize := Value;
end;{ Component constructor... }
constructor TFileSplitter.Create(AOwner: TComponent);
begin
inherited;
FFileName := '';
FSplitFileName := FFileName;
FOutDifferent := False;
FSize := 1457664;
FBufferSize := 1457664;
FReduceFirstSizeBy := 0;
Signature.Copyright := 'TFileSplitter by Jovan Sedlan';
Signature.NumberOfFiles := 0;
end;{ EraseFile deletes a file on disk }
procedure EraseFile(FN: TFileName);
var
f: File;begin
AssignFile(f, FN);
Erase(f);
end;{ StrZero returns a string representation of a Number,
Len characters long, with leading zeroes }
function StrZero(Number: LongInt; Len: Byte): String;
var
Temp: String;begin
Temp := Trim(IntToStr(Number));
Result := StringOfChar('0', Len - Length(Temp)) + Temp;
end;{ Split method does the actual work - splits a file into multiple files }
procedure TFileSplitter.Split;
var
i: Integer;
Continue: Boolean;
FileCount, PercentDone: Integer;
sFileName: TFileName;
BytesToRead, BytesWritten, BytesRead, BytesStored, LastSplitFileSize: LongInt;
TheSize: LongInt;begin
if FileExists(FFileName) then
begin
{ Make sure the filename is correct }
if FSplitFileName = '' then
FSplitFileName := ChangeFileExt(FFileName, '.SPL'); { Prepare for reading from file }
FFile := TFileStream.Create(FFileName, fmOpenRead);
GetMem(FBuffer, FBufferSize); { Calculate the number of resulting files }
FileCount := (FFile.Size + SizeOf(Signature)) div FSize;
LastSplitFileSize := (FFile.Size + SizeOf(Signature)) mod FSize;
if LastSplitFileSize <> 0 then
Inc(FileCount);
if (LastSplitFileSize + FReduceFirstSizeBy) > FSize then
Inc(FileCount);
Signature.NumberOfFiles := FileCount; try
{ Write resulting file(s) }
i := 1;
Continue := True;
sFileName := FSplitFileName;
while (i <= FileCount) do
begin
if Assigned(FOnNeedDisk) then
FOnNeedDisk(Self, i, Signature.NumberOfFiles, Continue); if Continue then
begin
{ Delete the resulting file if it exists }
if FileExists(sFileName) then
EraseFile(sFileName);
FSplitFile := TFileStream.Create(sFileName, fmCreate); BytesWritten := 0;
if i = 1 then
begin
{ Put the signature in the first split file }
FSplitFile.Write(Signature, SizeOf(Signature));
{ Write one file }
BytesToRead := FBufferSize;
if BytesToRead > FSize - FReduceFirstSizeBy then
BytesToRead := FSize - FReduceFirstSizeBy; BytesToRead := BytesToRead - SizeOf(Signature);
BytesWritten := SizeOf(Signature); { Real size of the split file }
TheSize := FSize - FReduceFirstSizeBy;
end
else
begin
{ Write one file }
BytesToRead := FBufferSize;
if BytesToRead > FSize then
BytesToRead := FSize; { Real size of the split file }
TheSize := FSize;
end; while BytesWritten < TheSize do
begin
if BytesToRead > TheSize - BytesWritten then
BytesToRead := TheSize - BytesWritten;
BytesRead := FFile.Read(FBuffer^, BytesToRead);
BytesStored := FSplitFile.Write(FBuffer^, BytesRead);
Inc(BytesWritten, BytesStored); { Call OnProgress event }
if Assigned(FOnProgress) then
begin
if i = FileCount then
PercentDone := (BytesWritten * 100) div LastSplitFileSize
else
PercentDone := (BytesWritten * 100) div TheSize;
FOnProgress(Self, PercentDone);
end; if FFile.Position = FFile.Size then
Break;
end;
FSplitFile.Free;
sFileName := ChangeFileExt(sFileName, '.' + StrZero(i, 3));
Inc(i);
end;
end;
finally
{ Clean up }
FreeMem(FBuffer);
FFile.Free;
end;
end
else
raise EFileError.Create('Input file ''' + FFileName + ''' does not exist.');
end;
extension of the original file must be set in FileName property }
procedure TFileSplitter.UnSplit;
var
i: Integer;
Continue: Boolean;
sFileName: TFileName;
BytesRead, TotalRead: LongInt;begin
if FileExists(FSplitFileName) then
begin
{ Make sure the filename is correct }
if FFileName = '' then
FFileName := ChangeFileExt(FSplitFileName, '.XXX'); { Delete the resulting file if it exists }
if FileExists(FFileName) then
EraseFile(FFileName); { Prepare for writing to file }
FFile := TFileStream.Create(FFileName, fmCreate);
GetMem(FBuffer, FBufferSize); try
i := 0;
sFileName := FSplitFileName; { Read files one by one and write to resulting file }
Continue := True;
Signature.NumberOfFiles := 0;
while Continue do
begin
if Assigned(FOnNeedDisk) then
FOnNeedDisk(Self, i + 1, Signature.NumberOfFiles, Continue); if Continue then
begin
if FileExists(sFileName) then
begin
try
FSplitFile := TFileStream.Create(sFileName, fmOpenRead); { Read the signature from the first split file }
if i = 0 then
FSplitFile.Read(Signature, SizeOf(Signature)); TotalRead := 0;
while FSplitFile.Size <> FSplitFile.Position do
begin
BytesRead := FSplitFile.Read(FBuffer^, FBufferSize);
FFile.Write(FBuffer^, BytesRead);
TotalRead := TotalRead + BytesRead; { Call OnProgress event }
if Assigned(FOnProgress) then
FOnProgress(Self, (TotalRead * 100) div FSplitFile.Size);
end;
finally
FSplitFile.Free;
end;
Inc(i);
sFileName := ChangeFileExt(sFileName, '.' + StrZero(i, 3));
end
else
Continue := False;
end;
end;
finally
FreeMem(FBuffer);
FFile.Free;
end;
end
else
raise EFileError.Create('Input file ''' + FSplitFileName + ''' does not exist.');
end;{ Register component and property editors }
procedure Register;
begin
RegisterComponents('SEDLAN A.D.', [TFileSplitter]);
RegisterPropertyEditor(TypeInfo(TFileName), TFileSplitter, 'FileName', TFSFileNameProperty);
RegisterPropertyEditor(TypeInfo(TFileName), TFileSplitter, 'SplitFileName', TFSSplitFileNameProperty);
end;end.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
F:TFileStream;
Buffer: Array of Char;
Buf: PChar;
F1:TFileStream;
begin
//把1.bmp分开
F:=TFileStream.Create('E:\1.bmp',fmOPenRead);
Setlength(Buffer,F.size);
Buf:=@Buffer;
F.Position:=0;
F.Read(Buf,F.Size);
F1:=TFileStream.Create('E:\1_1.bmp',fmCreate);
F1.Write(Buf,100);
F1.Free;
F1:=TFileStream.Create('E:\1_2.bmp',fmCreate);
Buf:=Buf+100;
F1.Write(Buf,F.Size-100);
F1.Free;
F.Free;
end;procedure TForm1.Button2Click(Sender: TObject);
var
F:TFileStream;
F1: TFileStream;
Buffer: Array of Char;
buf:PChar;
begin
F:=TFileStream.Create('E:\H1.bmp',FmCreate);
F1:=TFileStream.Create('E:\1_1.bmp',fmOpenRead);
buf:=@buffer;
if length(buffer)<F1.Size then SetLength(Buffer,f1.size);
F1.Read(buf,F1.Size);
F.Write(buf,F1.Size);
F1.Free;
F1:=TFileStream.Create('E:\1_2.bmp',fmOpenRead);
if length(buffer)<=F1.Size then SetLength(Buffer,f1.size);
F1.Read(buf,F1.Size);
F.Write(buf,F1.Size);
F1.free;
F.Free;
end;end.