2017-03-07 2 views
1

다음 코드를 사용하여 dataTable에서 데이터를 serialize합니다.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 인 경우 발생합니다. 동일한 것은 비 직렬화를 나타냅니다. 그래서 내가 부분적으로 serialize/deserialize하기를 원한다.

모든 것을 시도하고 어디에서나 검색했습니다. 이걸 도와 주셔서 감사합니다.

+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

감사합니다. !!! :) 나는 맥주를 소유하고있어 :) –