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

El uso del código anterior funciona a la perfección. Sin embargo, cuando acortarlo a:Xml Serialización sin eliminación

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

consigo la siguiente excepción al intentar deserializar el archivo users.xml en la misma prueba: El proceso no puede acceder al 'users.xml' archivo porque es siendo utilizado por otro proceso.

La causa parece ser que el método File.Create devuelve un FileStream abierto, que no puedo cerrar ya que no tengo una referencia del mismo.

¿Es malo o Microsoft? ;-)

+0

Hay un concepto subyacente aquí que te falta (que es fácil de hacer) - lee sobre el uso de objetos que usan la interfaz iDisposable. – overslacked

Respuesta

11

El problema es que en el segundo ejemplo abres un identificador de archivo del que nunca te deshaces, por lo que la segunda vez que llames a tu método lanzará la excepción que estás describiendo. El primer fragmento es la forma preferible (Puede eliminar el bit file_stream.Close(); Stream.Dispose() lo llamará automáticamente).

+0

Gracias, mi mal es entonces. – Dabblernl

0

Si no tenía la instrucción "using", pero conservaba el cierre, habría estado bien.

[Editar: Agregado tratar ... Por último, gracias 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() 
} 

En ese caso, sin embargo, es preferible botar porque sabe todo las acciones que debe tomar para limpiar, incluyendo cerca (y cualquier otra cosa).

+0

no te olvides de probar ... ¡por fin! – Cheeso

+0

wow que usar la sintaxis es conveniente ... gracias Cheeso –

2

Debe serializar en un bloque try finally para que pueda asegurarse de que el archivo se cierra/elimina independientemente de si tiene éxito o falla. Esto es lo que la palabra clave usa para usted.

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

File.Create debe colocarse fuera del bloque try como se muestra en mi respuesta anterior. Si lo coloca dentro del bloque try, debe verificar fs para obtener una referencia nula antes del cierre. A continuación, se muestra el código corregido, pero mi primera respuesta es mucho mejor ya que puede evitar esta comprobación.

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() 
} 
Cuestiones relacionadas