음, 데이터를 스트림에 저장 은입니다. 진정한 속임수는 어떤 종류입니까? 예를 들어, 나는 당신이 모든 것을 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;
}
}
당신이 할 수있는 경우 :도 엔디 언은 독자와 작가 사이의 동일 함을 현재의 가정을 해결할 것
int
(길이)에 대한 가변 길이 인코딩을 사용하여 (예를 들어)이 최적화 될 수 있습니다 최대 문자열 길이를 설정하면 각 항목에 대해 디스크에서이 길이를 사용하고 검색하지 않고 해당 위치에 직접 액세스 할 수 있습니다. Pos = maxstringlength * position. 디스크에 바이트를 낭비하지만 시나리오에 따라 프로그램을 도울 수 있습니다. –@Mikael : 네, 데이터베이스 용어로 볼 때 '[n] varchar (m)'과 '[n] char (m)'의 차이점을 보는 또 다른 방법입니다. 데이터가 매우 효과적 일 수있는 알려지고 현명한 최대 길이가있는 경우 - 응답으로 게시하지 않는 이유는 무엇입니까? –