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

来源:http://www.cnblogs.com/5207/archive/2016/01/06/5105949.html
-Advertisement-
Play Games

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


最近做個發郵件的功能,需要將日誌文件通過郵件發送回來用於分析,但是日誌文件可能會超級大,測算下來一天可能會有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集成在程式中還是挺方便的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Background ProcessingRZ01Job Scheduling MonitorSM36Schedule Background JobSM36WIZJob definition wizardSM37Overview of job selectionSM37BSimple version...
  • IOC:Inversion of Control(控制反轉)。IOC它所體現的並不是一種技術,而是一種思想,一種將設計好的對象交給容器來管理的思想。IOC的核心思想就體現在控制、反轉這兩個詞上面,要理解就必須要理解幾個問題: 1、誰控制誰?在傳統的開發工作中,我們一般都是主動去new一個對象,這個是...
  • 每一種語言都有相應的關鍵詞,每個關鍵詞都有他獨特的作用,來看看swfit中的關鍵詞:關鍵詞:用來聲明的:class, deinit, enum, extension, func, import, init, let, protocol, static, struct, subscript, type...
  • 使用的系統是Ubuntu 11.10.資料庫是MySQL。MySQL資料庫環境配置首先需要安裝MySQL客戶端和伺服器,命令行安裝方式為:[cpp]view plaincopyprint?sudoapt-getinstallmysql-servermysql-client然後,要使用C語言編程訪問數...
  • 以後再做記錄5.1、對於HashMap需要掌握以下幾點Map的創建:HashMap()往Map中添加鍵值對:即put(Object key, Object value)方法獲取Map中的單個對象:即get(Object key)方法刪除Map中的對象:即remove(Object key)方法判斷對...
  • #import int main(int argc, const char * argv[]) { @autoreleasepool { /** * length獲取字元串長度,即獲取字元個數 */// NSString *str=...
  • Java 7支持整個目錄樹的遍歷;Demo:import java.io.IOException;import java.nio.file.FileVisitResult;import java.nio.file.Files;import java.nio.file.Path;import java...
  • Java中PrintStream(列印輸出流)PrintStream 是列印輸出流,它繼承於FilterOutputStream。PrintStream 是用來裝飾其它輸出流。它能為其他輸出流添加了功能,使它們能夠方便地列印各種數據值表示形式。與其他輸出流不同,PrintStream 永遠不會拋出 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...