2010-01-02 4 views
3

직렬화를 사용하지 않고 문자열 배열을 스트림에 저장할 수있는 방법은 무엇입니까?직렬화를 사용하지 않고 문자열 배열을 스트림에 유지할 수 있습니까?

길이가 다를 수 있으므로 특히 문자열에 관심이 있습니다. 또한 스트림에서 배열을 복원 할 수 있어야합니다. 더 중요한 것은 잠재적으로 배열이 커질 수 있기 때문에 전체 배열을 메모리에 읽지 않고 배열의 조각 만 읽을 수 있기를 원합니다.

P. 나는 바퀴가 등을 재발명해서는 안된다는 데이터베이스가 있다는 것을 알고 있지만 손으로 ​​만든 해결책을 선택할 이유가 있습니다.

감사합니다.

답변

3

음, 데이터를 스트림에 저장 입니다. 진정한 속임수는 어떤 종류입니까? 예를 들어, 나는 당신이 모든 것을 deserialize 할 것을 요구하는 XmlSerializer이나 BinaryFormatter과 같은 것을 말하고 있다고 가정하지만, 반드시 필요한 것은 아닙니다.

각 문자열에 길이 접두사를 쓰면 원치 않는 과거 항목을 찾을 수 있습니다. 다른 옵션은 (별도로) 오프셋 색인을 작성하는 것이지만 때로는 잔인합니다.

기본 예로서, 여기 s는 전체 스트림을 읽거나 불필요한 문자열을 역 직렬화없이 "jkl"이고;

static void Main() 
{ 
    byte[] raw; 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     // serialize all 
     List<string> data = new List<string> { 
      "abc", "def", "ghi", "jkl", "mno", "pqr" }; 
     foreach (string s in data) 
     { 
      byte[] buffer = Encoding.UTF8.GetBytes(s); 
      byte[] lenBuffer = BitConverter.GetBytes(buffer.Length); 
      ms.Write(lenBuffer, 0, lenBuffer.Length); 
      ms.Write(buffer, 0, buffer.Length); 
     } 
     raw = ms.ToArray(); 
    } 
    using (MemoryStream ms = new MemoryStream(raw)) 
    { 
     int offset = 3, len; 
     byte[] buffer = new byte[128]; 
     while (offset-- > 0) 
     { 
      Read(ms, ref buffer, 4); 
      len = BitConverter.ToInt32(buffer, 0); 
      ms.Seek(len, SeekOrigin.Current); // assume seekable, but 
               // easy to read past if not 
     } 
     Read(ms, ref buffer, 4); 
     len = BitConverter.ToInt32(buffer, 0); 
     Read(ms, ref buffer, len); 
     string s = Encoding.UTF8.GetString(buffer, 0, len); 
    } 
} 
static void Read(Stream stream, ref byte[] buffer, int count) 
{ 
    if (buffer.Length < count) buffer = new byte[count]; 
    int offset = 0; 
    while (count > 0) 
    { 
     int bytes = stream.Read(buffer, offset, count); 
     if (bytes <= 0) throw new EndOfStreamException(); 
     offset += bytes; 
     count -= bytes; 
    } 
} 
+0

당신이 할 수있는 경우 :도 엔디 언은 독자와 작가 사이의 동일 함을 현재의 가정을 해결할 것 int (길이)에 대한 가변 길이 인코딩을 사용하여 (예를 들어)이 최적화 될 수 있습니다 최대 문자열 길이를 설정하면 각 항목에 대해 디스크에서이 길이를 사용하고 검색하지 않고 해당 위치에 직접 액세스 할 수 있습니다. Pos = maxstringlength * position. 디스크에 바이트를 낭비하지만 시나리오에 따라 프로그램을 도울 수 있습니다. –

+0

@Mikael : 네, 데이터베이스 용어로 볼 때 '[n] varchar (m)'과 '[n] char (m)'의 차이점을 보는 또 다른 방법입니다. 데이터가 매우 효과적 일 수있는 알려지고 현명한 최대 길이가있는 경우 - 응답으로 게시하지 않는 이유는 무엇입니까? –

관련 문제