程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 學習筆記:7z在delphi在的應用,7zdelphi

學習筆記:7z在delphi在的應用,7zdelphi

編輯:Delphi

學習筆記:7z在delphi在的應用,7zdelphi


最近做個發郵件的功能,需要將日志文件通過郵件發送回來用於分析,但是日志文件可能會超級大,測算下來一天可能會有800M的大小。所以壓縮是不可避免了,delphi中的默認壓縮算法整了半天不太好使,就看了看7z,在windows下有dll那麼就用它吧。

下載7z.dll,還有一個delphi的開發sdk文件,sevenzip.pas。有這兩個就可以了。

壓縮

使用超級簡單

procedure TForm1.Button1Click(Sender: TObject);
var
  Arch: I7zOutArchive;
  Counter: Integer;
  sZipFile: string;
begin
  OpenDialog1.Filter := '所有文件|*.*';
  OpenDialog1.Options := OpenDialog1.Options + [ofAllowMultiSelect];
  if OpenDialog1.Execute then
  begin
    Memo1.Lines.Append('開始壓縮');
    Arch := CreateOutArchive(CLSID_CFormat7z);
    Arch.SetProgressCallback(nil, ProgressCallback);
    for Counter := 0 to OpenDialog1.Files.Count - 1 do
      Arch.AddFile(OpenDialog1.Files[Counter], ExtractFileName(OpenDialog1.Files[Counter]));

    SetCompressionLevel(Arch, 5);
    SevenZipSetCompressionMethod(Arch, m7LZMA);//算法設置,很重要哦
    sZipFile := FRootPath+'test.7z';
    Arch.SaveToFile(sZipFile);
    Memo1.Lines.Append('完成壓縮,文件生成於:' + sZipFile);
    CalcZipScale(sZipFile, ProgressBar1.Max);    
  end;
end;

此方法通過文件選擇框可以壓縮多個文件成一個壓縮包。這裡有點要注意的是使用:m7LZMA這個算法壓縮比特別高,好像針對文本類型的會很好。我試了400M的文本壓縮後5M左右吧。這個壓縮率還是挺可觀的。

另外有個需求是用於壓縮整個目錄的,方法也很簡單:

procedure TForm1.Button3Click(Sender: TObject);
var
  Arch: I7zOutArchive;
  Counter: Integer;
  sZipFile: string;
begin
  if not DirectoryExists(edtPath.Text) then
  begin
    ShowMessage('請輸入有效目錄');
    edtPath.SetFocus;
  end;

  Memo1.Lines.Add('開始壓縮');
  Arch := CreateOutArchive(CLSID_CFormat7z);
  Arch.SetProgressCallback(nil, ProgressCallback);
  Arch.AddFiles(edtPath.Text, 'memData', '*.*', False);

  SetCompressionLevel(Arch, 5);
  SevenZipSetCompressionMethod(Arch, m7LZMA);//算法設置,很重要哦
  sZipFile := FRootPath+'path.7z';
  Arch.SaveToFile(sZipFile);
  Memo1.Lines.Append('完成壓縮,文件生成於:' + sZipFile);
  CalcZipScale(sZipFile, ProgressBar1.Max);
end;

沒什麼大的區別,就是調用壓縮方法時使用AddFiles,這個方法的參數要注意一下:

procedure AddFiles(const Dir, Path, Wildcard: string; recurse: boolean); stdcall;

Dir:待壓縮的目錄

Path:壓縮包中的目錄(就是壓縮後在壓縮包裡的根目錄)

Wildcard:通配符,可以用於過濾文件(*.*)

recurse:遞歸子目錄

其他的壓縮我就沒去試了,生成7z的包用winrar反正是可以打開和解壓的。

解壓

7z也提供了解壓的算法,但是不同的壓縮算法生成的壓縮包格式是不同的,需要指定解壓類型來解壓。但我看7z裡支持的算法類型還是很全的,於是就整了個If列表。

先看看解壓的方法:

procedure TForm1.Button2Click(Sender: TObject);
var
  Arch: I7zInArchive;
  Counter: Integer;
  sExtractPath: string;
begin
  OpenDialog1.Filter := '壓縮文件|*.zip;*.rar;*.7z';
  OpenDialog1.Options := OpenDialog1.Options - [ofAllowMultiSelect];
  if OpenDialog1.Execute then
  begin
    Memo1.Lines.Append('開始解壓');
    try
      Arch := GetInArchiveByFileExt(ExtractFileExt(OpenDialog1.FileName));
      Arch.SetProgressCallback(nil, ProgressCallback);
      Arch.OpenFile(OpenDialog1.FileName);
      for Counter := 0 to Arch.NumberOfItems - 1 do
      begin
        if not Arch.ItemIsFolder[Counter] then
          Memo1.Lines.Append('包含文件:' + Arch.ItemPath[Counter]);
      end;

      sExtractPath := FRootPath + getShotFileName(ExtractFileName(OpenDialog1.FileName));
      if ForceDirectories(sExtractPath) then
      begin
        Arch.ExtractTo(sExtractPath);
        Memo1.Lines.Append('完成解壓');
      end
      else
        ShowMessage('無法解壓到指定目錄');
    except
      on e: Exception do
        Memo1.Lines.Add('發生異常:' + e.Message)
    end;

    Arch := nil;
    Memo1.Lines.Add('-----------------------------------------------------------');
  end;
end;

解壓時是調用ExtractTo來解壓的,簡單。只不過要通過後綴來選擇特定的解壓對象需要單獨處理一下,寫了個方法:

function TForm1.GetInArchiveByFileExt(AExt: string): I7zInArchive;
var
  sExt: string;
begin
  sExt := UpperCase(AExt);
  if (sExt='.ZIP') or (sExt='.JAR') or (sExt='.XPI') then
    Result := CreateInArchive(CLSID_CFormatZip)
  else if (sExt='.BZ2') or (sExt='.BZIP2') or (sExt='.TBZ2') or (sExt='.TBZ') then
    Result := CreateInArchive(CLSID_CFormatBZ2)
  else if (sExt='.RAR') or (sExt='.R00') then
    Result := CreateInArchive(CLSID_CFormatRar)
  else if (sExt='.ARJ') then
    Result := CreateInArchive(CLSID_CFormatArj)
  else if (sExt='.Z') or (sExt='.TAZ') then
    Result := CreateInArchive(CLSID_CFormatZ)
  else if (sExt='.LZH') or (sExt='.LHA') then
    Result := CreateInArchive(CLSID_CFormatLzh)
  else if (sExt='.7Z') then
    Result := CreateInArchive(CLSID_CFormat7z)
  else if (sExt='.CAB') then
    Result := CreateInArchive(CLSID_CFormatCab)
  else if (sExt='.NSIS') then
    Result := CreateInArchive(CLSID_CFormatNsis)
  else if (sExt='.LZMA') then
    Result := CreateInArchive(CLSID_CFormatLzma)
  else if (sExt='.LZMA86') then
    Result := CreateInArchive(CLSID_CFormatLzma86)
  else if (sExt='.EXE') then
    Result := CreateInArchive(CLSID_CFormatPe)
  else if (sExt='.PE') or (sExt='.DLL') or (sExt='.SYS') then
    Result := CreateInArchive(CLSID_CFormatPe)
  else if (sExt='.ELF') then
    Result := CreateInArchive(CLSID_CFormatElf)
  else if (sExt='.MACHO') then
    Result := CreateInArchive(CLSID_CFormatMacho)
  else if (sExt='.UDF') then
    Result := CreateInArchive(CLSID_CFormatUdf)
  else if (sExt='.XAR') then
    Result := CreateInArchive(CLSID_CFormatXar)
  else if (sExt='.MUB') then
    Result := CreateInArchive(CLSID_CFormatMub)
  else if (sExt='.HFS') or (sExt='.CD') then
    Result := CreateInArchive(CLSID_CFormatHfs)
  else if (sExt='.DMG') then
    Result := CreateInArchive(CLSID_CFormatDmg)
  else if (sExt='.MSI') or (sExt='.DOC') or (sExt='.XLS') or (sExt='.PPT') then
    Result := CreateInArchive(CLSID_CFormatCompound)
  else if (sExt='.WIM') or (sExt='.SWM') then
    Result := CreateInArchive(CLSID_CFormatWim)
  else if (sExt='.ISO') then
    Result := CreateInArchive(CLSID_CFormatIso)
  else if (sExt='.BKF') then
    Result := CreateInArchive(CLSID_CFormatBkf)
  else if (sExt='.CHM') or (sExt='.CHI') or (sExt='.CHQ') or (sExt='.CHW')
          or (sExt='.HXS') or (sExt='.HXI') or (sExt='.HXR') or (sExt='.HXQ')
          or (sExt='.HXW') or (sExt='.LIT') then
    Result := CreateInArchive(CLSID_CFormatChm)
  else if  (sExt='.001') then
    Result := CreateInArchive(CLSID_CFormatSplit)
  else if  (sExt='.RPM') then
    Result := CreateInArchive(CLSID_CFormatRpm)
  else if  (sExt='.DEB') then
    Result := CreateInArchive(CLSID_CFormatDeb)
  else if  (sExt='.CPIO') then
    Result := CreateInArchive(CLSID_CFormatCpio)
  else if  (sExt='.TAR') then
    Result := CreateInArchive(CLSID_CFormatTar)
  else if  (sExt='.GZ') or (sExt='.GZIP') or (sExt='.TGZ') or (sExt='.TPZ') then
    Result := CreateInArchive(CLSID_CFormatGZip)
  else
    Result := CreateInArchive(CLSID_CFormatZip);
end;

沒想到7z的完成度這麼高,還是非常方便的。

 

後記:以前在.net平台上調用過7z,只不過是使用shell方式調用的7z.exe。用命令感覺會麻煩一些,使用dll集成在程序中還是挺方便的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved