嗯,将数据保存到流中
是
序列化;真正的诀窍是:什么类型。例如,我假设你说的是
XmlSerializer
或
BinaryFormatter
这要求您对整个事物进行反序列化,但这并不总是必要的。
通过使用长度前缀编写每个字符串,您应该能够很容易地查找过去不需要的项目。另一种选择是(单独)写一个偏移索引,但这有时是多余的。
作为一个
基本的
例子,
s
这是
"jkl"
,
没有
它读取整个流或反序列化不需要的字符串;注意,它可以通过(例如)使用可变长度编码来优化
int
(长度),这也将修正当前的假设,即读写器之间的结尾是相同的:
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;
}
}