2016-09-21 73 views
2

我做兩個功能的加入,在TFileStream的劃分文件,代碼:文件分割成一個TFileStream的

加入

procedure TFormHome.btnJoinClick(Sender: TObject); 
var 
    InStream, OutStream: TFileStream; 
    OutFileName, InFileName1, InFileName2: string; 
begin 
    OutFileName := 'salida.out'; 
    InFileName1 := 'image.jpg'; 
    InFileName2 := 'test.exe'; 
    OutStream := TFileStream.Create(OutFileName, fmCreate); 
    try 
    InStream := TFileStream.Create(InFileName1, fmOpenRead); 
    ShowMessage(IntToStr(InStream.Size)); 
    try 
     OutStream.CopyFrom(InStream, InStream.Size); 
    finally 
     InStream.Free; 
    end; 
    InStream := TFileStream.Create(InFileName2, fmOpenRead); 
    ShowMessage(IntToStr(InStream.Size)); 
    try 
     OutStream.CopyFrom(InStream, InStream.Size); 
    finally 
     InStream.Free; 
    end; 
    finally 
    OutStream.Free; 
    end; 
end; 

鴻溝

procedure TFormHome.btnUnJoinClick(Sender: TObject); 
var 
    Source, Target: TStream; 
    Buffer: array of Byte; 
    i: Integer; 
    SourceName, TargetNames: string; 
    SizeTargets: Integer; 
begin 
    SourceName := 'salida.out'; 
    TargetNames := 'test.exe'; 
    SizeTargets := 2232832; 
    Source := TFileStream.Create(SourceName, fmOpenRead); 
    Target := TFileStream.Create(TargetNames, fmCreate); 
    try 
    SetLength(Buffer, SizeTargets); 
    Source.ReadBuffer(Pointer(Buffer)^, Length(Buffer)); 
    Target.WriteBuffer(Buffer[0], Length(Buffer)); 
    finally 
    Target.Free; 
    end; 
end; 

的問題是,當我劃分文件時,可執行文件中斷並運行時,我想顯示如下錯誤:

Windows can not find the file "route ..." Make sure the name is spelled correctly and try again 

The version of this file is not compatible with the version of Windows you are running ... (and then talking about 32 or 64 bits) 

檢查與所述可執行的第二功能的大小是好的。

的問題是,在第二個代碼,結果都在文件被破壞

我該如何解決這個問題?

+0

的問題是,在第二個代碼中導致所有文件被破壞 – TheHune

回答

4

您正在將多個輸入文件連接在一起,而不在輸出中指示一個文件結束且下一個開始。您的分隔代碼不知道哪些字節屬於JPG,哪些字節屬於EXE。

例如,您顯示的分隔代碼是提取JPG字節並將其保存到.exe文件。所以當然.exe文件不會正確運行。

爲了提取EXE,您必須先提取/跳過JPG,這意味着您必須知道JPG中有多少個字節。所以,你需要輸入文件大小存儲所加入的輸出,而不僅僅是他們的數據,例如:

procedure TFormHome.btnJoinClick(Sender: TObject); 
var 
    OutStream: TFileStream; 

    procedure AddFile(const FileName: sstring); 
    var 
    InStream: TStream; 
    Size: Int64; 
    begin 
    InStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); 
    try 
     Size := InStream.Size; 
     OutStream.WriteBuffer(Size, SizeOf(Size)); 
     OutStream.CopyFrom(InStream, Size); 
    finally 
     InStream.Free; 
    end; 
    end; 

begin 
    OutStream := TFileStream.Create('salida.out', fmCreate); 
    try 
    AddFile('image.jpg'); 
    AddFile('test.exe'); 
    finally 
    OutStream.Free; 
    end; 
end; 

procedure TFormHome.btnUnJoinClick(Sender: TObject); 
var 
    Source: TStream; 

    procedure SkipFile; 
    var 
    Size: Int64; 
    begin 
    Source.ReadBuffer(Size, SizeOf(Size)); 
    Source.Seek(Size, soCurrent); 
    end; 

    procedure ExtractFile(const FileName: string); 
    var 
    Target: TStream; 
    Size: Int64; 
    begin 
    Source.ReadBuffer(Size, SizeOf(Size)); 

    Target := TFileStream.Create(FileName, fmCreate); 
    try 
     Target.CopyFrom(Source, Size); 
    finally 
     Target.Free; 
    end; 
    end; 

begin 
    Source := TFileStream.Create('salida.out', fmOpenRead or fmShareDenyWrite); 
    try 
    SkipFile; 
    ExtractFile('test.exe'); 
    finally 
    Source.Free; 
    end; 
end; 

我建議你考慮將文件名以及:

procedure TFormHome.btnJoinClick(Sender: TObject); 
var 
    OutStream: TFileStream; 

    procedure AddFile(const FileName: string); 
    var 
    InStream: TStream; 
    Name: UTF8String; 
    Len: Integer; 
    FileSize, TotalSize: Int64; 
    begin 
    InStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); 
    try 
     Name := UTF8String(ExtractFileName(FileName)); 
     Len := Length(Name); 

     FileSize := InStream.Size; 

     TotalSize := SizeOf(Len) + Len + SizeOf(FileSize) + FileSize; 
     OutStream.WriteBuffer(TotalSize, SizeOf(TotalSize)); 

     OutStream.WriteBuffer(Len, SizeOf(Len)); 
     OutStream.WriteBuffer(PAnsiChar(Name)^, Len); 
     OutStream.WriteBuffer(FileSize, SizeOf(FileSize)); 
     OutStream.CopyFrom(InStream, FileSize); 
    finally 
     InStream.Free; 
    end; 
    end; 

begin 
    OutStream := TFileStream.Create('salida.out', fmCreate); 
    try 
    AddFile('image.jpg'); 
    AddFile('test.exe'); 
    finally 
    OutStream.Free; 
    end; 
end; 

procedure TFormHome.btnUnJoinClick(Sender: TObject); 
var 
    Source: TStream; 

    procedure SkipFile; 
    var 
    TotalSize: Int64; 
    begin 
    Source.ReadBuffer(TotalSize, SizeOf(TotalSize)); 
    Source.Seek(TotalSize, soCurrent); 
    end; 

    procedure ExtractFile; 
    var 
    Target: TStream; 
    TotalSize, FileSize: Int64; 
    Name: UTF8String; 
    Len: Integer; 
    Pos: Int64; 
    begin 
    Source.ReadBuffer(TotalSize, SizeOf(TotalSize)); 
    Pos := Source.Position; 

    Source.ReadBuffer(Len, SizeOf(Len)); 
    SetLength(Name, Len); 
    Source.ReadBuffer(PAnsiChar(Name)^, Len); 

    Source.ReadBuffer(FileSize, SizeOf(FileSize)); 

    Target := TFileStream.Create(String(Name), fmCreate); 
    try 
     Target.CopyFrom(Source, FileSize); 
    finally 
     Target.Free; 
    end; 

    if (Source.Position - Pos) <> TotalSize then 
     raise Exception.Create('Extract failed. Bad position'); 
    end; 

begin 
    Source := TFileStream.Create('salida.out', fmOpenRead or fmShareDenyWrite); 
    try 
    SkipFile; 
    ExtractFile; 
    finally 
    Source.Free; 
    end; 
end; 
+0

謝謝Remy Lebeau。 – TheHune