Seek 使用BinaryWriter时查找特定值

Seek 使用BinaryWriter时查找特定值,seek,binarywriter,fixed-size-types,Seek,Binarywriter,Fixed Size Types,我发现很难表达自己,所以我将直接进入代码 FileStream stream = new FileStream("//ignoreThis//demo.bin", FileMode.Append, FileAccess.Write, FileShare.Write)); BinaryWriter writer = new BinaryWriter(stream); writer.Write(myNum); writer.Write(myStrin

我发现很难表达自己,所以我将直接进入代码

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”的末尾添加新数据。现在,我正在尝试编写一个方法,可以在其中查找我的第三个实例(我不确定是否可以这样调用它)。主要的问题是变量的大小不同,尽管我使用这段代码将字符串的“固定”长度设置为20 (我知道当有人写入长度超过20的字符串时,它不起作用,但我已经编写了验证,以确保它们不会超过此限制)

下面是我用来使字符串长度恒定的代码

public String MakeFixedSize(int length, String inputString)
{
    return inputString.PadRight(length, '\0');
}

据我所知,int的大小和长度是固定的,我在这个程序中使用它(不是在上面的代码中)

有很多方法可以做到这一点,我不确定哪种方法最适合您的情况

如果你能够并且想要创建严格固定大小的记录,你可以直接寻找合适的位置。对于大量数据,这可能更快

或者,您也可以依靠,在每个字符串前面加上两个长度字节的前缀,然后读取正确的字符数

如果您想保持更灵活和简单,可以使用
二进制格式化程序进行序列化

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();
创建可序列化的类:

[Serializable]
public class MyClass
{
    public string Name;
    public int Number;
}
然后,您可以使用
二进制格式化程序将多个实例写入磁盘:

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();
然后重新阅读,可能在
列表中
,仍然使用相同的格式化程序:

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));
短字符串只能获得一个单字节长度计数器:

较长的字符串会得到两个字节的前缀,对于可变大小的字符串,您必须逐步遍历记录,计算下一个偏移量

我真的想不出你为什么要那样做,除非数据真的很大


嗯,有时要求就是要求,有时需要提问。

看看——它是德语的,但我希望你可以转换语言。该代码解释了编写时要执行的操作(使用binarywriter读取字符串。其要点是binarywriter以“长度前缀”的形式写入字符串,因此您可以通过查看前两个字节来计算长度。-但是您最好使用
BinaryFormatter
并序列化数据。请看“直接写入文件夹”是什么意思?每条记录一个文件?我是eant文件。我希望以可区分的方式分隔每条记录,以便在不使用序列化的情况下加快搜索速度(即使用字节数组,通过BinaryWriter存储并通过解析将其读回).我已经有了解析和诸如此类的代码,但是我需要一种很好的方法来分离记录,但是对于可变大小的记录,直接查找是不起作用的。在我的示例中,虽然是在逐个记录的基础上,但回读是快速而直接的。事实并非如此(明确地)但是,解析字节只是类成员类型。因此,如果我理解正确,我需要在字符串或序列化之前加前缀(这在本任务中是不允许的)。我的问题是,为什么我最初编写的使字符串具有固定大小的代码不能与binarywriter配合使用,但在使用序列化时效果很好?该任务特别要求我不使用序列化,而是直接存储值。您可以扩展字符串的前缀吗?我不熟悉这个概念。该任务解释它,而不是ell:length前缀字符串通过在字符串前面加上包含该字符串长度的单个字节或单词来表示字符串长度。此方法首先将字符串长度写入UTF-7编码的无符号整数,然后使用BinaryWriter实例的当前编码将这么多字符写入流。它是值得研究的代码,在这里您可以看到如何读回各种类型。。