2009-05-17 3 views
6
 using (var file_stream = File.Create("users.xml")) 
     { 
      var serializer = new XmlSerializer(typeof(PasswordManager)); 
      serializer.Serialize(file_stream, this); 
      file_stream.Close(); 
     } 

Использование вышеуказанного кода работает отлично. Однако, когда я укоротить до:Xml Сериализация без утилизации

  var serializer = new XmlSerializer(typeof(PasswordManager)); 
      serializer.Serialize(File.Create("users.xml"), this); 

я получаю следующее исключение при попытке десериализации файл users.xml в том же тесте: Процесс не может получить доступ к файлу «users.xml», потому что это используя другой процесс.

Причина, по всей видимости, в том, что метод File.Create возвращает открытый FileStream, который я не могу закрыть, поскольку я не придерживаюсь его ссылки.

Мой плохой, или Microsoft? ;-)

+0

Здесь есть базовая концепция, которую вам не хватает (что легко сделать) - прочитайте об использовании объектов, которые используют интерфейс iDisposable. – overslacked

ответ

11

Проблема заключается в том, что во втором примере вы открываете дескриптор файла, который вы никогда не уничтожаете, поэтому во второй раз, когда вы вызываете свой метод, он будет генерировать исключение, которое вы описываете. Первый фрагмент является предпочтительным (вы можете удалить бит file_stream.Close() - он будет автоматически вызван Stream.Dispose()).

+0

Спасибо, мой плохой тогда. – Dabblernl

0

Если у вас не было инструкции «using», но сохранено закрытие, вы бы все в порядке.

[Edit: Добавлено попробовать ... наконец, благодаря 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 является предпочтительным, поскольку он знает все действия, которые он должен предпринять, чтобы очистить, включая закрытие (и все остальное).

+0

не забудьте попробовать ... наконец! – Cheeso

+0

wow, что синтаксис удобен ... спасибо Cheeso –

2

Вы должны сделать сериализацию в файле , попробуйте, наконец,, чтобы вы могли убедиться, что файл закрыт/удален независимо от успеха или сбоя. Это то, что делает с использованием ключевого слова.

var serializer = new XmlSerializer(typeof(PasswordManager)); 
var fs = File.Create("users.xml"); 
try { serializer.Serialize(fs,this); } 
finally { fs.Close(); } 
0

Файл. Создание должно быть размещено вне блока 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() 
} 
Смежные вопросы