HOWTO · Csharp

C# で文字列を圧縮および解凍する

この記事では、C# で文字列サイズを圧縮または解凍する方法を学習します。

この記事では、System.IO ファイルシステムに圧縮方法を適用する方法を説明します。

Compression 名前空間は、文字列の値を圧縮および解凍できます。値を圧縮すると、バイト数が大幅に削減されます。

圧縮の定義

物理学では、圧縮とは、質量に内向きに作用する力に起因するサイズの減少を指します。データ圧縮について話すときは、コンテンツを認識できるほど失うことなく、データをよりコンパクトな形式に変更することを指します。

データ圧縮は、アルゴリズムを使用して人間が実際に使用できる数のビットに既存の情報をエンコードするプロセスです。さまざまなアルゴリズムの有効性は、程度によって異なります。

それでも、一般に、データの圧縮に必要な時間や CPU に必要な処理能力の点で妥協が必要です。

C# の.NET データ圧縮アルゴリズム

代替の圧縮方法はたくさんありますが、この議論のために、GZip に集中します。SharpZipLib などのサードパーティライブラリを利用することは可能ですが、.NET Framework にネイティブで、System.IO.Compression 名前空間にある GZipStream クラスを使用します。

さらに、文字列データの圧縮と解凍を強く強調します。バイト配列やストリームなど、他の種類を処理するための手順は多少変更されます。

C#GZip を使用して文字列を圧縮する

GZipStream の最も基本的な実装では、ユーザーは基になるストリームと圧縮オプションを入力として提供する必要があります。圧縮モードは、データを圧縮するか解凍するかを決定します。基になるストリームは、圧縮方法に基づいて変更されます。

以下のコードは、基になる出力ストリームとしてメモリストリームを使用します。出力ストリームは GZipStream コンテナにラップされます。

入力データを GZipStream に送信すると、データはパイプラインを下って圧縮形式で出力ストリームに移動します。書き込みアクションを独自の使用ブロックに配置することにより、データがクリーンアップされることを保証する場合があります。

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();
  }
}

GZip を使用して C# の文字列を解凍する

データを解凍すると、解凍されるストリームが入力ストリームになります。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