using (var file_stream = File.Create("users.xml"))
{
var serializer = new XmlSerializer(typeof(PasswordManager));
serializer.Serialize(file_stream, this);
file_stream.Close();
}
使用上面的代码非常有效。但是,当我把它缩短为:
var serializer = new XmlSerializer(typeof(PasswordManager));
serializer.Serialize(File.Create("users.xml"), this);
当我尝试在同一测试中反序列化users.xml文件时,我收到以下异常: 该进程无法访问文件'users.xml',因为它正由另一个进程使用。
原因似乎是File.Create方法返回一个打开的FileStream,我无法关闭,因为我没有保留它的引用。
我的坏,还是微软? ; - )
答案 0 :(得分:11)
问题在于,在第二个示例中,您打开了一个永远不会丢弃的文件句柄,因此第二次调用方法时,它将抛出您描述的异常。第一个片段是更好的方式(你可以删除file_stream.Close()位 - 它将由Stream.Dispose()自动调用。
答案 1 :(得分:2)
您应该在 try finally 块中序列化,这样您就可以确保无论成功与否,都会关闭/处置该文件。这就是使用关键字为您所做的事情。
var serializer = new XmlSerializer(typeof(PasswordManager));
var fs = File.Create("users.xml");
try { serializer.Serialize(fs,this); }
finally { fs.Close(); }
答案 2 :(得分:0)
如果你没有“使用”声明,但保留了关闭,那你就没事了。
[编辑:添加尝试...最后,谢谢cheeso]
var serializer = new XmlSerializer(typeof(PasswordManager));
FileStream fs;
try
{
fs = File.Create("users.xml");
serializer.Serialize(fs, this);
}
finally
{
fs.Close(); // or fs.Dispose()
}
但是,在这种情况下,Dispose更可取,因为它知道所有清理时必须采取的行动,包括关闭(以及其他任何事情)。
答案 3 :(得分:0)
File.Create应该放在try块之外,如我之前的回答所示。如果将其放在try块中,则需要在关闭前检查 fs 是否为空引用。以下显示了更正后的代码,但我的第一个答案要好得多,因为您可以避免这种检查。
serializer = new XmlSerializer(typeof(PasswordManager));
FileStream fs;
try
{
fs = File.Create("users.xml");
serializer.Serialize(fs, this);
}
finally
{
if (fs != null) // in case File.Create fails
fs.Close(); // or fs.Dispose()
}