2010-12-07 31 views
2

Très bien, le code suivant est en production depuis plus d'un an sans modification. Cela a très bien fonctionné. Au cours du dernier mois, plus d'une poignée de machines ont signalé que les documents XML étaient complètement vides. Ils ne contiennent même pas d'en-tête XML. Je ne peux pas dupliquer les fichiers qui sont soudainement vides, je ne peux pas non plus suggérer un moyen pour que cela se produise. J'espère que quelqu'un a eu un problème similaire qu'ils ont résolu.XmlSerializer créera-t-il des documents vides?

La plupart des machines qui utilisent ce code l'utilisent depuis environ un an, voire plus. Les fichiers vides utilisés pour contenir des données et des listes. Les fichiers ne se sérialisent pas en même temps. Le sauvegarder/sérialiser l'un après l'autre avant que le programme se termine.

Mes questions: est-il possible que le code ci-dessous crée un fichier vide? Quoi d'autre les rendrait soudainement vides? Est-ce que quelqu'un d'autre a eu des problèmes avec XML-serializer au cours du dernier mois? (Ce problème n'est survenu que le mois dernier pour les versions stables depuis plus de 3 mois.)

Si vous avez des questions ou si quelque chose manque, demandez s'il vous plaît. Il y a aussi une grande variété de types que je sérialiser ... donc si vous pouvez l'imaginer j'ai probablement quelque chose de similaire qui est sérialisé.

public class BackEnd<T> { 
public string FileSaveLocation = "this gets set on startup"; 
public bool DisabledSerial; 
public virtual void BeforeDeserialize() { } 
public virtual void BeforeSerialize() { } 
public virtual void OnSuccessfulSerialize() { } 
protected virtual void OnSuccessfulDeserialize(ListBackEnd<T> tmpList) { } 
protected virtual void OnDeserialize(ListBackEnd<T> tmpList) { } 

public virtual void serialize() 
    { 
     if (DisabledSerial) 
      return; 
     try 
     { 
      BeforeSerialize(); 

      using (TextWriter textWrite = new StreamWriter(FileSaveLocation)) 
      { 
       (new XmlSerializer(this.GetType())).Serialize(textWrite, this); 
       Debug.WriteLine(" [S]"); 
       textWrite.Close(); 
      } 
      OnSuccessfulSerialize(); 
     } 
     catch (Exception e) 
     { 
      Static.Backup.XmlFile(FileSaveLocation); 
      Log.ErrorCatch(e, 
       "xml", 
       "serialize - " + typeof(T) + " - " + (new FileInfo(FileSaveLocation)).Name); 
     } 

    } 

    public virtual object deserialize(TextReader reader) 
    { 
     if (this.DisabledSerial) 
      return false; 


     ListBackEnd<T> tmp = null; 


     this.BeforeDeserialize(); 

     if (reader == null && !File.Exists(this.FileSaveLocation)) 
     { 
      Log.Write(Family.Error, 
       "xml", 
       "deserialize - " + this.GetType() + " - file not found. " + (new FileInfo(FileSaveLocation)).Name); 
     } 
     else 
     { 
      try 
      { 
       using (TextReader textRead = ((reader == null) ? new StreamReader(this.FileSaveLocation) : reader)) 
       { 
        tmp = (ListBackEnd<T>)this.get_serializer().Deserialize(textRead); 
        Debug.WriteLine(" [D]"); 
        textRead.Close(); 
       } 
       OnSuccessfulDeserialize(tmp); 

       if (tmp != null) 
       { 
        this._Items = tmp._Items; 
        this.AutoIncrementSeed = tmp.AutoIncrementSeed; 
        if (this._Items.Count > this.AutoIncrementSeed && this._Items[0] is ItemStorage) 
         this.AutoIncrementSeed = this._Items.Max(item => (item as ItemStorage).Key); 
       } 
      } 
      catch (Exception e) 
      { 
       // this only copies the file 
       Static.Backup.XmlFile(FileSaveLocation); 
       // this only logs the exception 
       Log.ErrorCatch(e, 
        "xml", 
        "deserialize - " + typeof(T) + " - " + (new FileInfo(FileSaveLocation)).Name); 
      } 
     } 
     //{ Log.ErrorCatch(e, "xml", "deserialize" + this.GetType() + " - " + this.FileSaveLocation); } 

     OnDeserialize(tmp); 

     tmp = null; 

     return (_Items.Count > 0); 
    } 
} 

Répondre

3

La seule raison pour laquelle je pense que cela se produise est que cette ligne:

(new XmlSerializer(this.GetType())).Serialize(textWrite, this); 

lance une exception et TextWriter est créé et disposé sans avoir jamais rien écrit à elle. Je regarderais votre journal pour les erreurs.

Qu'est-

Static.Backup.XmlFile(FileSaveLocation); 

faire?

+0

Je vais prendre ça. Il ne m'est jamais venu à l'esprit que des exceptions à l'intérieur d'une instruction using videraient le fichier comme ça. Il y a d'autres choses qui se passent bien. Très apprécié Dustin. – Gauthier

+0

Bon pour aider;) –

+0

Il fait juste une copie du fichier. Si, pour une raison ou une autre, je n'ai pas ajouté correctement les attributs de champ optionnels, l'original sera sauvegardé. – Gauthier

7

Nous avons rencontré ce problème plusieurs fois à $ WORK, avec le symptôme étant un fichier vide de la taille correcte mais rempli avec zéro octet.

La solution que nous avons trouvé était de définir la valeur writethrough sur le FileStream:

using (Stream file = new FileStream(settingTemp, FileMode.Create, 
            FileAccess.Write, FileShare.None, 
            0x1000, FileOptions.WriteThrough)) 
{ 
    using (StreamWriter sw = new StreamWriter(file)) 
    { 
     ... 
    } 
} 
+0

Vous êtes un saint, merci de le mentionner. – jemidiah

+0

FYI: Ceci désactive le cache d'écriture (tel qu'utilisé dans Windows) et valide directement le fichier (peut-être devoir vider/autoflush?). 0x1000 est la taille de tampon par défaut de 4096. – urbanhusky

+0

Je suis confronté au même problème. Savez-vous quelle pourrait être la cause première? –