0

データが書き込まれるときにログファイルを圧縮しています。次のようになります。

using (var fs = new FileStream("Test.gz", FileMode.Create, FileAccess.Write, FileShare.None))
{
  using (var compress = new GZipStream(fs, CompressionMode.Compress))
  {
    for (int i = 0; i < 1000000; i++)
    {
      // Clearly this isn't what is happening in production, just 
      // a simply example
      byte[] message = RandomBytes();
      compress.Write(message, 0, message.Length);

      // Flush to disk (in production we will do this every x lines, 
      // or x milliseconds, whichever comes first)
      if (i % 20 == 0)
      {
        compress.Flush();
      }
    }
  }
}

私が確認したいのは、プロセスがクラッシュまたは強制終了された場合でも、アーカイブは有効で読み取り可能であるということです。前回のフラッシュ以降は何でも安全だと思っていましたが、代わりにアーカイブが破損してしまいました。

フラッシュするたびに読み取り可能なアーカイブを作成する方法はありますか?

注:他の何かで目的の結果が得られる場合は、GZipStreamを使用する必要はありません。

4

3 に答える 3

2

オプションは、Windowsに圧縮を処理させることです。ログファイルを保存しているフォルダで圧縮を有効にするだけです。圧縮ファイルをコピーするときに注意する必要のあるパフォーマンス上の考慮事項がいくつかあります。NT圧縮がGZipStream他の圧縮オプションと比較してどれだけうまく機能するかはわかりません。おそらく、圧縮率とCPU負荷を比較することをお勧めします。

フォルダ全体で圧縮を有効にしたくない場合は、圧縮ファイルを開くオプションもあります。私はこれを試していませんが、調べてみてください:http ://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/1b63b4a4-b197-4286-8f3f-af2498e3afe5

于 2013-03-27T14:19:49.540 に答える
1

朗報:GZipはストリーミング形式です。したがって、ストリームの最後での破損は、すでに書き込まれている最初に影響を与えることはできません。

したがって、ストリーミング書き込みが任意の時点で中断された場合でも、ほとんどのストリームは良好です。そこから読み取り、最初の例外で停止する小さなツールを自分で作成できます。

エラーのないソリューションが必要な場合は、ログをx秒ごとに1つのファイルに分割することをお勧めします(おそらくx = 1または10?)。拡張子が「.gz.tmp」のファイルに書き込み、ファイルが完全に書き込まれて閉じられたら、名前を「.gz」に変更します。

于 2013-03-27T13:32:31.110 に答える
1

はい、しかしそれは単にフラッシュするよりも複雑です。zlibディストリビューションのgzlog.hgzlog.cを見てください。それはあなたが望むことを正確に行い、短いログエントリをgzipファイルに効率的に追加し、常に有効なgzipファイルを残します。また、プロセス中のクラッシュやシャットダウンに対する保護もあり、有効なgzipファイルを残し、ログエントリを失うことはありません。

GZIPStreamを使用しないことをお勧めします。バグがあり、必要な機能を提供していません。代わりに、zlibへのインターフェースとしてDotNetZipを使用してください。

于 2013-03-27T14:56:36.803 に答える