2017-02-06 10 views
0

私はオブジェクト(Carクラス)をシリアル化してxmlファイルとして保存しています。しかし時々(非常にまれなイベント、私はそれを複製することはできません)ファイルサイズが正しいにもかかわらず、null文字(ASCIIコード0の文字)のみを含むファイルを取得します。XMLシリアル化の結果、ファイルがヌル文字でいっぱいになる

public void SaveCar(Car car) 
{ 
    var serializer = new XmlSerializer(typeof(Car)); 
    using (var stream = new MemoryStream()) 
    { 
     serializer.Serialize(stream, car); 
     byte[] binaryCar = stream.ToArray(); 
     FileHelper.WriteAllBytes(@"C:\car.xml", binaryCar); 
    } 
} 

FileHelper.WriteAllBytesが存在しない場合、それは親ディレクトリを作成することを除いて、System.IO.File.WriteAllBytesと同じです。

public static class FileHelper 
{ 
    public static void WriteAllBytes(string path, byte[] bytes) 
    { 
     CreateParentDirectoryForPathIfDoesntExist(path); 
     File.WriteAllBytes(path, bytes); 
    } 

    public static void CreateParentDirectoryForPathIfDoesntExist(string filePath) 
    { 
     var file = new FileInfo(filePath); 
     if (file.Exists) 
     { 
      return; 
     } 

     if (file.Directory != null && !file.Directory.Exists) 
     { 
      Directory.CreateDirectory(file.Directory.FullName); 
     } 
    } 
} 

何が原因なのですか?エンコーディングの問題?

+1

でテストしたときでしょうか?特定のファイルについては?特定の車ですか? 'NUL'文字を持つファイルの作成を確実に実証する[mcve]は役に立ちます。 –

+3

そして 'FileHelper'についてもっと具体的になります。候補の問題のソースのように見えます。 –

+1

あなたの質問に 'FileHelper'のコードを入れてください。 –

答えて

1

あなたの「SaveCar」メソッドの継ぎ目うまく動作するように、私はあなたがあなたの例からの最大の違いは、シリアライザ・インスタンスは、一度作成され、UTF8エンコーディングを強制されていることである次の実装

public class XmlCar { 
    public static readonly Encoding Utf8Encoding = Encoding.UTF8; 
    public static readonly XmlSerializer CarSerializer = new XmlSerializer(typeof(Car)); 
    public static Car Load(string path) { 
     using (var stream = new StreamReader(path, Utf8Encoding, false)) { 
      using (var reader = XmlReader.Create(stream)) { 
       return (Car)CarSerializer.Deserialize(reader); 
      } 
     } 
    } 
    public static void Save(string path, Car instance) { 
     using (var stream = new StreamWriter(path, false, Utf8Encoding)) { 
      using (var writer = XmlWriter.Create(stream)) { 
       CarSerializer.Serialize(writer, instance); 
      } 
     } 
    } 
} 

を使用することができますしたいです。

あなたの方法は、以下のクラスで試みた

[XmlRoot] 
public class Car { 
    [XmlAttribute] 
    public string Model { get; set; } 
    [XmlAttribute] 
    public string Plate { get; set; } 
    [XmlArray] 
    [XmlArrayItem] 
    public List<Part> Parts { get; set; } 
} 
[XmlRoot] 
public class Part { 
    [XmlAttribute] 
    public string Type { get; set; } 
    [XmlAttribute] 
    public string Code { get; set; } 
    [XmlAttribute] 
    public int Quantity { get; set; } 
} 

このサンプルでは、​​このサイトにあるサンプルから導出されますのでご注意ください。

Yoursメソッドは、ファイル名の制御に対応するために少し変更されました。

public static void SaveCar(Car car, int i) 
    { 
     var serializer = new XmlSerializer(typeof(Car)); 
     using (var stream = new MemoryStream()) 
     { 
      serializer.Serialize(stream, car); 
      byte[] binaryCar = stream.ToArray(); 
      File.WriteAllBytes("car"+ i + ".xml", binaryCar); 
     } 
    } 

方法が '時々' は、次の機能

static void Main(string[] args) { 

     var random = new Random(); 
     var cars = new List<Car>(); 

     for (var c = 0; c < 10; c++) { 
      var car = new Car() { 
       Model = Guid.NewGuid().ToString(), 
       Plate = (random.Next(500) + 500).ToString(), 
       Parts = new List<Part>() 
      }; 
      for (var p = 0; p < 100; p++) { 
       car.Parts.Add(new Part() { 
        Type = Guid.NewGuid().ToString(), 
        Code = (random.Next(500) + 1500).ToString(), 
        Quantity = random.Next(100) + 1 
       }); 
      } 
      SaveCar(car, c); 
      cars.Add(XmlCar.Load("car" + c + ".xml")); 
     } 
    } 
+1

['XmlTextReader'](https://msdn.microsoft.com/en-us/library/system.xml.xmltextreader(v = vs.110).aspx)および[' XmlTextWriter'](https:// msdn Microsoft.com/ja-ja/library/system.xml.xmltextwriter(v = vs.110).aspx)はお勧めできません(リンクされたドキュメントを参照)。 'XmlReader.Create'と' XmlWriter.Create'を使うべきです。 'StreamReader'と' StreamWriter'はデフォルトでUTF8になりますが、ファイルパスを受け入れる 'Create'オーバーロードを使用する場合はどちらも必須ではありません。これらの変更はあまり害を及ぼさないけれども、私は彼らが質問に答えるのを見ません。 –

+0

ループで複製しようとしてくれてありがとう、残念ながら私はこの方法でもエラーを見つけることができませんでした。エラーの原因が見つからない場合は、おそらくコード化の不足が原因で問題が発生している可能性があります。 – Bedford

+1

@Bedfordでは、後で読むストリームを書くときはいつでも、Flush()を呼び出していることを確認してください(サポートされていれば、それがすべて入っていることを確認してください)。また、次の読み込みの前にストリームの先頭に位置を移動することが有用であることが判明するかもしれません。 – recineshto

関連する問題