2017-05-16 104 views
0

私は5GB以上の記録ファイル(バイナリファイル)を持っています。私はそのファイルを読んで、サーバーに送信するのに必要なデータをフィルタしなければなりません。C#で大きなバイナリファイル(5GB)をバイト配列に読み込みますか?

バイトの[]配列は、ファイルデータの2GBまでサポートしています。誰かがすでにこのような状況に対処していたなら、助けが必要です。

using (FileStream str = File.OpenRead(textBox2.Text)) 
{ 
     int itemSectionStart = 0x00000000; 
     BinaryReader breader = new BinaryReader(str); 
     breader.BaseStream.Position = itemSectionStart; 
     int length = (int)breader.BaseStream.Length; 
     byte[] itemSection = breader.ReadBytes(length); //first frame data 
} 

問題:

1: Length is crossing the range of integer. 
2: tried using long and unint but byte[] only supports integer 

編集。

もう1つのアプローチは、フレームバッファのデータを読み込みます。私のフレームバッファサイズが24000であるとします。バイト配列は多くのフレームデータを格納してからフレームデータを処理し、バイト配列をフラッシュして別の24000フレームデータを格納します。バイナリファイルの最後まで続けるまで。

+4

あなたは本当に一度にメモリ内のすべてのデータが必要ですか?データのフィルタリングにストリーミングアプローチを実装する必要があります。 –

+0

はい....ファイル内の特定のパターンを読み取ってその上でフィルタリングを適用する必要があります – user5794230

+1

ファイル全体をメモリに読み込むのではなく、可能であればビット単位でファイルを処理することをお勧めします。例えば最初のチャンクを読み込み、それをフィルタリングしてサーバに送信する(または一時ファイルに書き込む)前に、次のチャンクを読み込んで処理してください。どのようなフィルタリングをしているかによって、複数のパスが必要になることがあります。どのようなフィルタリングが必要なのか、さらに詳しく説明できますか? – Justin

答えて

0

大きなファイルを一度に読むことはできないので、ファイルを分割して処理する必要があります。

OR 

バッファの概念を使用してファイルを読み込み、そのバッファのデータを読み終えたら、そのバッファをフラッシュします。

私は同じ問題に直面したので、私はバッファベースのアプローチを試み、それは私のために働いた。

  FileStream inputTempFile = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.Read); 
      Buffer_value = 1024; 
      byte[] Array_buffer = new byte[Buffer_value]; 
      while ((bytesRead = inputTempFile.Read(Array_buffer, 0, Buffer_value)) > 0) 
      { 
       for (int z = 0; z < Array_buffer.Length; z = z + 4) 
       { 
        string temp_id = BitConverter.ToString(Array_buffer, z, 4); 
        string[] temp_strArrayID = temp_id.Split(new char[] { '-' }); 
        string temp_ArraydataID = temp_strArrayID[0] + temp_strArrayID[1] + temp_strArrayID[2] + temp_strArrayID[3]; 
       } 
      } 

この方法でデータを処理できます。

私の場合、私はバッファのデータをリストに読み込もうとしていましたが、2GBのデータがメモリ例外をスローするまで正常に動作します。

私が従ったアプローチは、バッファーからデータを読み取り、必要なフィルターを適用し、フィルター・データをテキスト・ファイルに書き込み、そのファイルを処理します。

//テキストファイルのアプローチ

  FileStream inputTempFile = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.Read); 
      Buffer_value = 1024; 
      StreamWriter writer = new StreamWriter(Path, true); 
      byte[] Array_buffer = new byte[Buffer_value]; 
      while ((bytesRead = inputTempFile.Read(Array_buffer, 0, Buffer_value)) > 0) 
      { 
       for (int z = 0; z < Array_buffer.Length; z = z + 4) 
       { 
       string temp_id = BitConverter.ToString(Array_buffer, z, 4); 
       string[] temp_strArrayID = temp_id.Split(new char[] { '-' }); 
       string temp_ArraydataID = temp_strArrayID[0] + temp_strArrayID[1] + temp_strArrayID[2] + temp_strArrayID[3]; 
       if(temp_ArraydataID =="XYZ Condition") 
       { 
        writer.WriteLine(temp_ArraydataID); 
       } 
       } 

      } 
      writer.Close(); 
0

コメントによると、あなたはストリームでファイルを読む必要があると思います。

int nbRead = 0; 
var step = 10000; 
byte[] buffer = new byte[step]; 
do 
{ 
    nbRead = breader.Read(buffer, 0, step); 
    hugeArray.Add(buffer); 

    foreach(var oneByte in hugeArray.SelectMany(part => part)) 
    { 
     // Here you can read byte by byte this subpart 
    } 
} 
while (nbRead > 0); 

あなたのニーズを十分に理解していれば、ファイルに特定のパターンを探しているでしょうか?

私はあなたのパターンの開始をバイトごとに調べることでそれができると思います。一度見つけたら、重要なバイトを読み始めることができます。重要なデータ全体が2GBを超える場合は、コメントに記載されているように、サーバーに複数の部分で送信する必要があります。

+0

バイト配列で完全なデータを後で保存したいのですが、そのデータを保存する際にフィルタリングを行いたい – user5794230

+0

@ user5794230うーん、*できません。複数のバイト配列が必要になるか、データをストリームする必要があります。あなたは管理されていないメモリやメモリマップされたファイルの膨大な部分を考慮することもできますが、ここでは過剰なようです。 –

+0

@ user5794230はい、私はそれを取得しますが、バイトサイズの制限のためにできません。あなたは本当にあなたがパートごとにろ過をすることはできませんか?それは私にとって大きなアルゴリズムの課題のようです:D。 Marc Gravell氏によると、https://msdn.microsoft.com/en-us/library/dd997372(v=vs.110).aspx?f=255&MSPPError=-2147217396も見ることができますが、決して使用しませんそれを助けることはできません。 – fharreau

関連する問題