LoginSignup
0
1

More than 3 years have passed since last update.

C#/.NET Frameworkで圧縮を同期的(リアルタイム)に行う方法

Last updated at Posted at 2019-09-03

はじめに

一般的な圧縮ストリームは、Close() メソッドか呼ばれるまでバッファリングしてしまって、リアルタイムな相互通信が必要な場合などには使えない。

compress0.png

zebedee などの通信を圧縮してくれるようなツールの互換プログラムは作りにくいだろう。

Javaの場合、SYNC_FLUSHモードが JDK7 から提供されているので、それを使えばいいが、.NET Framework の GZipStreamなどには提供されていない。

しかし、zlib.NET.dll にはSYNC_FLUSHモードが実装されてるので、それを使えばいいと思う。

バージョン

基本的に ver1.04 の話。

使い方(基本)

zlib.NET の demo フォルダを見ればわかると思うけど、一応メモ

zlib.ZOutputStream クラスも zlib.ZInputStream クラスもペースとなるストリームだけの一引数のコンストラクタの場合は、解凍
ペースとなるストリームと、圧縮レベルの二引数のコンストラクタの場合は、圧縮

後は、zlib.ZOutputStream#FlushMode に zlib.zlibConst.Z_SYNC_FLUSH を指定するだけ。

使い方(zlib.ZInputStream の落とし穴)

これ、なぜかSystem.IO.BinaryReader クラスを継承している。
にもかかわらず、BinaryReader クラスの各種メソッドは実装していない!!(ソースコードを見るとわかる)

唯一の実装が Read() と なぜか小文字始まりの read(byte[] b, int off, int len) だ。

まぁ、zlib.ZInputStream クラスをStreamとして包むラッパークラスを自作して、それの Read() を read() に繋げればいいだけの話なんだけど、私は BinaryReader として(BinaryReader.ReadByte()を)そのまま使っていて "解凍しねーな" と数日悩んだので、メモとして残しておくよ。

つまり、zlib.ZInputStream はBinaryReader を継承しているけど、Reader としては不十分なので、各自 Stream のラッパとして包み込んであげてから 再度Reader に包み込んであげればいいと思う。

BouncyCastle/C# でもできた

BouncyCastle/C# でもできた。

BouncyCastle/C# の Org.BouncyCastle.Utilities.Zlib.ZOutputStreamクラス/Org.BouncyCastle.Utilities.Zlib.ZInputStreamクラスの FlushMode プロパティがそれ。
このプロパティに Org.BouncyCastle.Utilities.Zlib.JZlib の Static 値を与えればいいと思う。
Org.BouncyCastle.Utilities.Zlib.JZlib.Z_SYNC_FLUSH とかを与えればいいと思う。

Javaでの捕捉

上の方に「Javaの場合、SYNC_FLUSHモードが JDK7 から提供されているので」と書いているが、Javaの場合は、
DeflaterOutputStream などだけではなく、java.util.zip.GZIPOutputStream にも、Sync_Flush (同期的圧縮)が付いている。(コンストラクタの第二引数に注目)

以上

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1