このチュートリアルでは、文字列や double などの基本データ型をメモリストリームに圧縮する方法、およびストリームからデータを読み取る際の展開方法について説明します。最終アプリケーションは、次の図のように表示されます。
Visual Studio プロジェクトで新しい WPF/Silverlight プロジェクトを作成します。ツールボックスから、ドラッグ&ドロップ操作を実行するか、コンポーネントをダブルクリックして、次のコントロールをフォームに追加します。
フォームの左端に並べて4個の Button コントロール(前の図を参照)。[プロパティ]ウィンドウで、各 Button コントロールに次の変更を加えます。
Button | Button.Content プロパティ | Button.Name プロパティ | Button.IsEnabled プロパティ |
---|---|---|---|
1 | 文字列の圧縮 | btnCompressString | True(デフォルト) |
2 | 文字列の圧縮解除 | btnExpandString | False |
3 | データの圧縮 | btnCompressData | True(デフォルト) |
4 | データの圧縮解除 | btnExpandData | False |
フォームの右上に RichTextBox。Height プロパティを 250 に設定し、TextWrapping プロパティを Wrap に設定します。
テキストボックスの下に Label コントロール。
ソリューションエクスプローラウィンドウに移動し、[すべてのファイルを表示]ボタンをクリックします。[参照]を右クリックし、[参照の追加]メニューオプションを選択します。リストから C1.WPF.Zip/C1.Silverlight.Zip アセンブリを選択するか、ファイルを参照して C1.WPF.Zip.dll/C1.Silverlight.Zipdll ファイルを探します。
[MainPage.xaml.vb]タブ(C# では[MainPage.xaml.cs]タブ)を選択するか、[表示]→[コード]を選択して、コードエディタを開きます。ファイルの上部に、次のステートメントを追加します。
これで、C1.WPF.Zip/C1.Silverlight.Zip アセンブリで定義されているオブジェクトがプロジェクトから可視になり、タイピング量を大きく減らすことができます。
[文字列の圧縮]コマンドボタンをダブルクリックし、btnCompressString_Click イベントを処理する次のコードを追加します。
最初に重要な行は、m_CompressedString というメンバ変数の宣言です。これは、圧縮データ(バイト配列としてエンコードされる)を保持するために使用されます。次に重要な行は、ユーティリティ関数 CompressString の呼び出しです。これは、指定された文字列をバイト配列に圧縮します。これを後から展開して、元の文字列を復元できます。残りのコードは、圧縮プロセスにかかる時間を計算し、その値をダイアログボックスに表示するために使用されます。
lenBefore 変数は(文字列の長さ)×2で計算されています。これは、.NET 文字列が Unicode であり、各文字が実際は2バイトあるためです。
CompressString 関数を実装する次のコードを追加します。
この関数は、最初に新しいメモリストリームを作成します。このストリームにより、圧縮データを保持するメモリバッファが自動的に割り当てられます。
次に、C1ZStreamWriter オブジェクトを作成し、それを新しいメモリストリームにアタッチします。C1ZStreamWriter オブジェクトに書き込まれたデータはすべて、圧縮されてメモリストリームに書き込まれます。
C1ZStreamWriter オブジェクトは、バイトデータとバイト配列を書き込むための基本ストリームメソッドを提供するだけです。文字列や整数などの他の基本型を書き込むには、StreamWriter オブジェクトを C1ZStreamWriter にアタッチします。次の図に、この関数の動作を示します。
StreamWriter の設定が終了したら、後はその Write メソッドを呼び出して、文字列を圧縮メモリストリームに書き込むだけです。書き込みが完了したら、Flush メソッドも呼び出して、キャッシュされている入力をすべて書き出します。
最後に、ToArray メソッドを使用して、メモリストリームによって作成されたバイト配列を返します。
文字列を展開するには、圧縮時に実行した手順を逆に実行する必要があります。[文字列の圧縮解除]ボタンをダブルクリックし、btnExpandString_Click イベントを処理する次のコードを追加します。
重要な行は、バイト配列を受け取って元の文字列を返すユーティリティ関数 ExpandString の呼び出しです。次のように ExpandString 関数のコードを追加します。
ここでプロジェクトを実行すると、文字列を圧縮/圧縮解除してみることができます。テキストボックス内のテキストを変更するか、テキストボックスに新しい内容を貼り付け、文字列を圧縮/展開して、どの程度圧縮されるかを確認できます。
文字列の圧縮と同様に、バイナリデータも簡単に圧縮できます。唯一の違いは、圧縮プログラムストリームに StreamWriter オブジェクトをアタッチする代わりに、BinaryWriter オブジェクトをアタッチするという点です。
[データの圧縮]ボタンをダブルクリックし、btnCompressData_Click イベントを処理する次のコードを追加します。
このコードは、最初に m_CompressedData というメンバ変数を宣言します。これは、圧縮データ(バイト配列としてエンコードされる)を保持するために使用されます。
MemoryStream、C1ZStreamWriter、BinaryWriter の各オブジェクトを前と同様に設定します。ただし、ここでは、StreamWriter の代わりに BinaryWriter を使用します。
次に、Write メソッドを使用して、データをストリームに書き込みます。BinaryWriter オブジェクトは、すべての基本オブジェクト型をストリームに書き込むことができるように、このメソッドをオーバーロードしています。最後に、前と同様に Flush メソッドを使用して、キャッシュされているデータがあればすべて圧縮ストリームに書き出します。
圧縮されたバイナリデータを展開するには、通常のストリームと同様に、圧縮解除プログラムストリームを設定し、データを読み取ります。
[データの圧縮解除]コマンドボタンに次の Click イベントハンドラコードを追加します。
このコードでは、データは読み取られますが、画面には表示されません。コードをデバッグモードでステップ実行すると、読み取られたデータが書き込まれたデータと同じであることを確認できます。
プロジェクトを実行し、[データの圧縮]/[データの圧縮解除]ボタンをクリックすると、データが 14,125 バイトの配列に保存されることがわかります。このデータを通常のストリームに保存する場合は、28,004 バイト(4 + 1000 * (4 + 8 * 3))が必要です。このため、元のサイズの約半分の大きさに圧縮されたことになります。
これで「メモリでのデータの圧縮」チュートリアルは終了です。