HOWTO · Csharp

在 C# 中壓縮和解壓縮字串

在本文中,我們將學習如何在 C# 中壓縮或解壓縮字串大小。

本頁內容

本文將演示我們如何將壓縮方法應用於 System.IO 檔案系統。

Compression 名稱空間可以壓縮和解壓縮字串的值。壓縮這些值應該會導致位元組大小顯著減少。

壓縮的定義

在物理學中,壓縮是指由向內作用在質量上的力導致的尺寸減小。當我們談論資料壓縮時,我們指的是將資料更改為更緊湊的格式,而不會造成任何明顯的內容丟失。

資料壓縮是使用演算法將已經存在的資訊編碼為儘可能少的位元的過程。各種演算法的功效有不同程度的不同。

儘管如此,它們通常會在壓縮資料所需的時間或 CPU 所需的處理能力方面做出妥協。

C# 中的 .NET 資料壓縮演算法

有許多替代壓縮方法,但為了討論,我們將集中討論 GZip。儘管使用諸如 SharpZipLib 之類的第三方庫是可行的,但我們將使用 .NET Framework 原生的 GZipStream 類並在 System.IO.Compression 名稱空間中找到。

此外,我們將強調壓縮和解壓縮字串資料;處理其他型別的過程,例如位元組陣列和流,將有所修改。

使用 GZip 在 C# 中壓縮字串

GZipStream 的最基本實現要求使用者提供底層流和壓縮選項作為輸入。壓縮模式決定你是要壓縮還是解壓縮資料;底層流根據壓縮方法而改變。

下面的程式碼使用記憶體流作為我們的底層輸出流。輸出流被包裝在一個 GZipStream 容器中。

當我們將輸入資料傳送到 GZipStream 時,資料會沿管道以壓縮形式傳輸到輸出流。我們可以通過將 Write 操作放在其自己的 using 塊中來保證資料已被清理。

save() 方法程式碼可在本文末尾的原始碼中找到。

public static byte[] Compress(string str) {
  var bytes = Encoding.UTF8.GetBytes(str);

  using (var msi = new MemoryStream(bytes)) using (var memoryStream = new MemoryStream()) {
    using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress)) {
      save(msi, gZipStream);
    }

    return memoryStream.ToArray();
  }
}

在 C# 中使用 GZip 解壓縮字串

解壓資料時,被解壓的流成為輸入流。GZipStream 將繼續包含它,但現在將反轉流程,以便從 GZipStream 讀取資料會將壓縮資料轉換為未壓縮資料。

CompressionMode.Decompress 模式用於解壓縮字串。

public static string Decompress(byte[] bytes) {
  using (var msi = new MemoryStream(bytes)) using (var memoryStream = new MemoryStream()) {
    using (var gZipStream = new GZipStream(msi, CompressionMode.Decompress)) {
      save(gZipStream, memoryStream);
    }

    return Encoding.UTF8.GetString(memoryStream.ToArray());
  }
}

在 C# 中壓縮和解壓縮字串的完整原始碼

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

class HelloWorld {
  public static void save(Stream source, Stream destination) {
    byte[] bytes = new byte[4096];

    int count;

    while ((count = source.Read(bytes, 0, bytes.Length)) != 0) {
      destination.Write(bytes, 0, count);
    }
  }

  public static byte[] Compress(string str) {
    var bytes = Encoding.UTF8.GetBytes(str);

    using (var msi = new MemoryStream(bytes)) using (var memoryStream = new MemoryStream()) {
      using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress)) {
        save(msi, gZipStream);
      }
      return memoryStream.ToArray();
    }
  }

  public static string Decompress(byte[] bytes) {
    using (var msi = new MemoryStream(bytes)) using (var memoryStream = new MemoryStream()) {
      using (var gZipStream = new GZipStream(msi, CompressionMode.Decompress)) {
        save(gZipStream, memoryStream);
      }

      return Encoding.UTF8.GetString(memoryStream.ToArray());
    }
  }

  static void Main(string[] args) {
    byte[] string1 = Compress("stringstringstringstringstringstringstringstring");
    Console.WriteLine("Zipped Size: " + string1.Length + " bytes");
    string string2 = Decompress(string1);
    Console.WriteLine("Unzipped Size: " + string2.Length + " bytes");
  }
}

輸出:

Zipped Size: 29 bytes
Unzipped Size: 48 bytes