使用 BinaryWriter 时寻求特定值
Seeking a particular value when using BinaryWriter
我觉得很难表达自己,所以我直接跳到代码中
FileStream stream = new FileStream("//ignoreThis//demo.bin",
FileMode.Append, FileAccess.Write, FileShare.Write));
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(myNum);
writer.Write(myString);
我可以多次调用此方法,我知道每次调用时,它都会在文件末尾添加新数据 'demo.bin'。现在我正在尝试编写一种方法,我可以在其中查找我的第 3 个 实例 (我不确定我是否可以这样称呼它)。主要问题是变量的大小不同,即使我使用这段代码使字符串的长度为 'fixed' 20
(我知道当有人写的字符串超过 20 时它不起作用,但我已经编写了验证以确保它们不超过此限制)
这是我用来使字符串成为恒定长度的代码
public String MakeFixedSize(int length, String inputString)
{
return inputString.PadRight(length, '[=11=]');
}
据我所知,int 和我在此程序中使用的 long 一样大小固定(不是在上面的代码中)
有很多方法可以做到这一点,我不确定哪种方法最适合您的情况。
如果您可以并且想要创建严格固定大小的记录,您可以直接去寻找合适的职位。对于大量数据,这可能会更快。
或者您可以依靠 BinaryWriter 为每个字符串添加两个长度字节的前缀,然后读取正确数量的字符..
如果您想保持更灵活并保持简单,您可以使用 BinaryFormatter
:
进行序列化
创建可序列化的 class:
[Serializable]
public class MyClass
{
public string Name;
public int Number;
}
然后您可以使用 BinaryFormatter
:
将多个实例写入磁盘
string fileName = "yourfileName";
FileStream stream = new FileStream(fileName,
FileMode.Append, FileAccess.Write, FileShare.Write);
var formatter = new BinaryFormatter();
formatter.Serialize(stream, new MyClass() { Name = "A", Number = 12365 });
formatter.Serialize(stream, new MyClass() { Name = "B", Number = 2365 });
formatter.Serialize(stream, new MyClass() { Name = "C", Number = 365 });
stream.Close();
然后读回来,可能在 List<T>
中,仍然使用相同的格式化程序:
FileStream stream2 = new FileStream(fileName, FileMode.Open, FileAccess.Read);
List<MyClass> myClassList = new List<MyClass>();
while (stream2.Position < stream2.Length)
myClassList.Add((MyClass)formatter.Deserialize(stream2));
现在您可以访问myClassList[2]
..
更新:
看来你也可以这样做,只要你确定记录长度:
using (BinaryWriter binWriter = new BinaryWriter(File.Open(fileName, FileMode.Create)))
{
binWriter.Write("RAller");
binWriter.Write(123);
binWriter.Write("RoBler");
binWriter.Write(23);
binWriter.Write("RolCer");
binWriter.Write(3);
binWriter.Write("RolDDr");
binWriter.Write(423);
binWriter.Write("REEler");
binWriter.Write(523);
binWriter.Write("RFFler");
binWriter.Write(66);
}
using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
{
// string < 255 seems to get only a one byte length prefix:
int recLen = 1 + 6 + 4;
br.BaseStream.Seek(recLen * 3, SeekOrigin.Begin);
string s = br.ReadString();
int i = br.ReadInt32();
}
短字符串只得到一个字节长度计数器:
较长的字符串有两个字节的前缀,对于可变大小,您必须遍历记录,计算下一个偏移量。
除非数据非常大,否则我真的无法想象你为什么想要那个。
好吧,需求有时就是这样,有时需要质疑..
我觉得很难表达自己,所以我直接跳到代码中
FileStream stream = new FileStream("//ignoreThis//demo.bin",
FileMode.Append, FileAccess.Write, FileShare.Write));
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(myNum);
writer.Write(myString);
我可以多次调用此方法,我知道每次调用时,它都会在文件末尾添加新数据 'demo.bin'。现在我正在尝试编写一种方法,我可以在其中查找我的第 3 个 实例 (我不确定我是否可以这样称呼它)。主要问题是变量的大小不同,即使我使用这段代码使字符串的长度为 'fixed' 20 (我知道当有人写的字符串超过 20 时它不起作用,但我已经编写了验证以确保它们不超过此限制)
这是我用来使字符串成为恒定长度的代码
public String MakeFixedSize(int length, String inputString)
{
return inputString.PadRight(length, '[=11=]');
}
据我所知,int 和我在此程序中使用的 long 一样大小固定(不是在上面的代码中)
有很多方法可以做到这一点,我不确定哪种方法最适合您的情况。
如果您可以并且想要创建严格固定大小的记录,您可以直接去寻找合适的职位。对于大量数据,这可能会更快。
或者您可以依靠 BinaryWriter 为每个字符串添加两个长度字节的前缀,然后读取正确数量的字符..
如果您想保持更灵活并保持简单,您可以使用 BinaryFormatter
:
创建可序列化的 class:
[Serializable]
public class MyClass
{
public string Name;
public int Number;
}
然后您可以使用 BinaryFormatter
:
string fileName = "yourfileName";
FileStream stream = new FileStream(fileName,
FileMode.Append, FileAccess.Write, FileShare.Write);
var formatter = new BinaryFormatter();
formatter.Serialize(stream, new MyClass() { Name = "A", Number = 12365 });
formatter.Serialize(stream, new MyClass() { Name = "B", Number = 2365 });
formatter.Serialize(stream, new MyClass() { Name = "C", Number = 365 });
stream.Close();
然后读回来,可能在 List<T>
中,仍然使用相同的格式化程序:
FileStream stream2 = new FileStream(fileName, FileMode.Open, FileAccess.Read);
List<MyClass> myClassList = new List<MyClass>();
while (stream2.Position < stream2.Length)
myClassList.Add((MyClass)formatter.Deserialize(stream2));
现在您可以访问myClassList[2]
..
更新:
看来你也可以这样做,只要你确定记录长度:
using (BinaryWriter binWriter = new BinaryWriter(File.Open(fileName, FileMode.Create)))
{
binWriter.Write("RAller");
binWriter.Write(123);
binWriter.Write("RoBler");
binWriter.Write(23);
binWriter.Write("RolCer");
binWriter.Write(3);
binWriter.Write("RolDDr");
binWriter.Write(423);
binWriter.Write("REEler");
binWriter.Write(523);
binWriter.Write("RFFler");
binWriter.Write(66);
}
using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
{
// string < 255 seems to get only a one byte length prefix:
int recLen = 1 + 6 + 4;
br.BaseStream.Seek(recLen * 3, SeekOrigin.Begin);
string s = br.ReadString();
int i = br.ReadInt32();
}
短字符串只得到一个字节长度计数器:
较长的字符串有两个字节的前缀,对于可变大小,您必须遍历记录,计算下一个偏移量。
除非数据非常大,否则我真的无法想象你为什么想要那个。
好吧,需求有时就是这样,有时需要质疑..