0

2 つのバイナリ ファイル"bigFile.bin""smallFile.bin". が含まれてい
ます。 比較を超えてそれを開くと、それが確認されます。 "bigFile.bin""smallFile.bin"

小さいファイルを大きい方から「result.bin」に抽出したいと思います"smallFile.bin"
2 つのキーワードがあります。1 つは開始位置 ("Section") 用で、もう 1 つは終了位置 ("Man") 用です。

私は次のことを試しました:

   byte[] bigFile = File.ReadAllBytes("bigFile.bin");
   UTF8Encoding enc = new UTF8Encoding();
   string text =  enc.GetString(bigFile);

   int startIndex = text.IndexOf("Section");
   int endIndex = text.IndexOf("Man");

   string smallFile = text.Substring(startIndex, endIndex - startIndex);

   File.WriteAllBytes("result.bin",enc.GetBytes(smallFile));

16 進表現の比較を示すビヨンド コンペアで、結果ファイルと元の小さなファイルを比較してみました。
バイト数は同じですが、そうでないものもあります。

たとえば、新しいファイルにはあります84が、古いファイルにはEF BF BD代わりにシーケンスがあります。

これらの違いの原因は何ですか? どこが間違っていますか?

4

1 に答える 1

0

バイナリ ファイルで作業しているため、テキスト関連の機能 (エンコーディングなどを含む) を使用しないでください。代わりに、バイト関連のメソッドを使用してください。

現在のコードは、次のようにすることで機能するように変換できます。

   byte[] bigFile = File.ReadAllBytes("bigFile.bin");

   int startIndex = /* assume we somehow know this */
   int endIndex = /* assume we somehow know this */

   var length = endIndex - startIndex;
   var smallFile = new byte[length];
   Array.Copy(bigFile, startIndex, smallFile, 0, length);
   File.WriteAllBytes("result.bin", smallFile);

見つけstartIndexendIndex、以前のテクニックを使用することもできますが、このようなものがより適切です。

ただし、これにはまだ問題があります。理由は次のとおりです。

  1. バイナリデータと「テキスト」の両方を同じファイルに詰め込むと、問題が複雑になります
  2. ここではまだ多くの不必要なコピーが行われています。入力Streamをバイト配列ではなくとして扱う必要があります
  3. 不必要なコピーよりもさらに悪いことに、ストリーム以外のソリューションでは、上記のようにすべての入力ファイルをメモリにロードする必要があるか (無駄)、コードが非常に複雑になります。

じゃあ何をすればいいの?

  1. メモリ内のファイルの内容をバイト配列として読み取らないでください。代わりに使用しFileStreamてください。
  2. をラップしStreamReaderて、FileStreamそれを使用して開始インデックスと終了インデックスのマーカーを見つけます。さらに良いことに、テキストを検索する必要がないように、ファイル形式を変更してください。
  3. startIndexとがわかったらlength、ストリーム関数を使用して入力ストリームの関連部分をシークし、lengthバイトを出力ストリームにコピーします。
于 2012-05-07T10:42:53.337 に答える