2017-03-07 4 views
1

次のコードを使用してdataTableからデータをシリアル化しています。BinaryReaderで行ごとに読み取る

var rows = new List<Dictionary<string, object[]>>(); 

私はDataTableから行を埋めて、それらを辞書に配置しています。以下の方法では、なぜ:)

using(var fileStream = new FileStream(@"D:\temp.bin", FileMode.Create, FileAccess.Write, FileShare.None)) 
using(var bw = new BinaryWriter(fileStream)) 
{ 
    foreach(Dictionary<string, object[]> row in rows) 
    { 
     byte[] bytes = ObjectToByteArray(row); 
     bw.Write(bytes); 
    } 
} 

に聞かないでください:

private static byte[] ObjectToByteArray(Dictionary<string, object[]> rows) 
{ 
    var bf = new BinaryFormatter(); 
    using(var ms = new MemoryStream()) 
    { 
     bf.Serialize(ms, rows); 
     return ms.ToArray(); 
    } 
} 

を私は何をしようとしていますと、それはBinaryReaderで可能であるならば、ライン毎にデシリアライズすることです。問題は、最初の行だけを読むことに固執していることです。私が達成したい何

は次のとおりです。

using(BinaryReader reader = new BinaryReader(File.Open(@"D:\temp.bin", FileMode.Open))) 
{ 
    int pos = 0; 
    int length = (int)reader.BaseStream.Length; 
    while(pos < length) 
    { 
     byte[] v = reader.ReadBytes(pos); 
     Dictionary<string, object[]> row = FromByteArray(v); 
     // Advance our position variable. 
     pos += row.Count; 
    } 
} 

最大の問題があるreader.ReadBytes(XXX) - >何が価値が読みすべきですか?私はそれを前もって知らない。私は行全体を読み、辞書に変換する必要があります。私は戻って変換に使用しています方法は次のとおりです。私はFromByteArrayは、最初の行のために正常に動作します言ったように

public static Dictionary<string, object[]> FromByteArray(byte[] data) 
{ 
    BinaryFormatter bf = new BinaryFormatter(); 
    using(MemoryStream ms = new MemoryStream(data)) 
    { 
     object obj = bf.Deserialize(ms); 
     return (Dictionary<string, object[]>)obj; 
    } 
} 

が、私は次の行を読むにどのような方法を見つけることではないのです。

私はBinarryFormatterを使用して完全なファイルをシリアライズすると、ファイルがそれほど大きくない場合にはパスします。それがOOMであれば発生します。デシリアライズの略です。そのため、私はそれを部分的に直列化/逆直列化する必要があります。

すべて試してみて、どこでも検索しました。これを手伝ってくれてありがとう。

+2

バイナリファイルの「行」のあなたの定義は何ですか?テキストファイルでは、改行は改行と改行で区切られます。おそらく、ファイルにデータを書き込むときには、各 "行"の長さとそのデータの長さを書き出す必要があります。ファイルを読み込むと、整数が読み込まれ、各行にその整数で指定されたバイト数が読み込まれます。 –

答えて

3

ファイルごとに、次の直列化オブジェクトの長さも保存します。

読み取り時には、すべての反復処理で最初に4バイト(reader.ReadInt32)が読み取られ、この値が取得され、この多くのバイトが読み取られてデシリアライズされます。

私はそれは次のようになりますと思う:

using(var fileStream = new FileStream(@"D:\temp.bin", FileMode.Create, FileAccess.Write, FileShare.None)) 
{ 
    using(var bw = new BinaryWriter(fileStream)) 
    { 
     foreach(Dictionary<string, object[]> row in rows) 
     { 
      byte[] bytes = ObjectToByteArray(row); 
      bw.Write(bytes.Length); 
      bw.Write(bytes); 
     } 
    } 
} 


using(BinaryReader reader = new BinaryReader(File.Open(@"D:\temp.bin", FileMode.Open))) 
{ 
    int length = (int)reader.BaseStream.Length; 
    while(reader.BaseStream.Position != length) 
    { 
     int bytesToRead = reader.ReadInt32(); 
     byte[] v = reader.ReadBytes(bytesToRead); 
     Dictionary<string, object[]> row = FromByteArray(v); 
    } 
}     
+0

感謝!!! :)おい、私はあなたにビールを持っています:) –

関連する問題