我onced设法在我的项目中创建bin文件。我将主键从int更改为Guid,并将代码从Main移到我的类Quote。目前我只能在所述文件中添加新条目。如果我删除它,当我尝试提供文件dummy-data时,会创建一个新文件(0字节)并且流获得 ArgumentException 。我正在尝试使用if循环来处理stream.Lenght == 0。
public static List<Quote> readBinaryToList() //Crashes if binfile is 0 bytes long
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(@"C:\Users\xxxxxx\Desktop\quotes.bin", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read);
if (stream.Length == 0)
{
Quote q = new Quote(Guid.NewGuid(), "Quote dummy", false);
List<Quote> quoteList = new List<Quote>();
quoteList.Add(q);
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bformatter.Serialize(stream, quoteList);
bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
List<Quote> quoteListTmp = (List<Quote>)bformatter.Deserialize(stream);
return quoteList;
}
else
{
List<Quote> quoteList = (List<Quote>)formatter.Deserialize(stream);
stream.Close();
return quoteList;
}
}
答案 0 :(得分:1)
文件正在以只读方式打开,序列化到文件将需要写入权限。
Stream stream = new FileStream(@"C:\temp\quotes.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
在尝试从中反序列化之前,也应该将流返回到开头。
stream.Seek(0, SeekOrigin.Begin);
FileStreams有一个“头”,所有的读写操作都在这里进行。在写入新流时,头部始终在最后,任何从末尾读取的尝试都将失败。某些流(例如NetworkStream
)表现不同,根本不允许搜索。
此外,FileStream的初始位置取决于文件的打开方式(基于指定的FileMode
)。问题中指定的FileMode将导致从文件开头开始的流位置,因此else
块中不需要这样做。
确保Quote类标记为[Serializable]
答案 1 :(得分:1)
正如前面的答案中所指出的,你必须给你的文件流写权限,这可以在它的构造函数中完成,然后你还应该将流的位置设置回0,你可以通过使用流&#39来实现这一点。 ; s位置属性。
您正在创建许多不必要的对象,这些对象实际上没有为我在下面省略这些方法的目的做出贡献。这样做,将流的Position属性设置为0是多余的,但我已将其留在评论中以显示其完成情况。
要考虑的其他一些事项:在using语句中声明文件流,以便在方法结束时将其处理掉,这意味着您可以在else语句中省略手动关闭。您的一些代码可以更简洁地编写,这只是个人偏好,但我认为最好将一些代码内联以尽可能消除噪音。在C#中使用PascalCase for Methods也是惯例。
public static List<Quote> ReadBinaryToList(){
using(Stream stream = new FileStream(@"quotes.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
IFormatter formatter = new BinaryFormatter();
if (stream.Length == 0) {
List<Quote> quoteList = new List<Quote> {new Quote(Guid.NewGuid(), "Quote dummy", false)};
formatter.Serialize(stream, quoteList);
//stream.Position = 0;
return quoteList;
}
else return (List<Quote>)formatter.Deserialize(stream);
}
}