7
       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,我无法关闭它,因为我没有保留它的引用。

我的坏,还是微软的?;-)

4

4 回答 4

12

问题是,在您的第二个示例中,您打开了一个从未处理过的文件句柄,因此第二次调用您的方法时,它将抛出您描述的异常。第一个片段是更可取的方式(您可以删除 file_stream.Close() 位 - Stream.Dispose() 将自动调用它)。

于 2009-05-17T20:20:21.433 回答
2

您应该在try finally块中进行序列化,以便确保无论成功还是失败,文件都已关闭/处置。这就是using关键字为您所做的。

var serializer = new XmlSerializer(typeof(PasswordManager));
var fs = File.Create("users.xml");
try { serializer.Serialize(fs,this); }
finally { fs.Close(); }
于 2009-06-29T07:53:18.730 回答
0

如果您没有“使用”语句,但保留了关闭,那么您就可以了。

[编辑:添加尝试......最后,谢谢奶酪]

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 更可取,因为它知道清理必须采取的所有操作,包括关闭(以及任何其他操作)。

于 2009-06-20T22:10:55.297 回答
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()
}
于 2009-06-29T23:28:45.330 回答