2016-07-02 16 views
-3

ユーザ設定のxmlファイルを自動ロードするプログラムを作成しますが、コードに新しい値を追加してプログラムが "Data5"値を持たないxmlファイルを読み込もうとすると問題が発生します。プログラムはエラーを返します。C#XML - 値はnullにはできません。パラメータ名:値

enter image description here

を、私はプログラムを閉じるとき、私は、ファイルがまだロックされている理由を私は理解していない別のプロセス

An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll 

Additional information: The process cannot access the file 'C:\Users\xxxxx\AppData\Local\APK Easy Tool\cfg.xml' because it is being used by another process. 

で使用されるファイルについては、別のエラーが発生しました。それはread.Close();の後で終了するはずです。私はxmlを読み込む前にxmlで新しい値を作成するようにしようとしましたが、変更された値を置き換えるためには良い考えではありません。ここに私のコードは

docs = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\APK"; 

です。

if (File.Exists(docs + @"\cfg.xml")) 
      { 
       try 
       { 
        XmlSerializer xs = new XmlSerializer(typeof(Data)); 
        FileStream read = new FileStream(docs + @"\cfg.xml", FileMode.Open, FileAccess.Read, FileShare.Read); 
        Data info = (Data)xs.Deserialize(read); 
        signApkCheckBox.Checked = bool.Parse(info.Data1); 
        pathOfApk.Text = info.Data2; 
        pathOfDec.Text = info.Data3; 
        pathOfCom.Text = info.Data4; 
        disableDebugChkBox.Checked = bool.Parse(info.Data5); 
        read.Close();    
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.Message); 
       } 
      } 

private void ApkForm_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    /* 
    Properties.Settings.Default.textBoxDec = pathOfDec.Text; 
    Properties.Settings.Default.textBoxCom = pathOfCom.Text; 
    Properties.Settings.Default.textBoxSelApk = pathOfApk.Text; 
    Properties.Settings.Default.checkSignApk = signApkCheckBox.Checked; 
    Properties.Settings.Default.Save(); 
    */ 

    Data info = new Data(); 
    info.Data1 = signApkCheckBox.Checked.ToString(); 
    info.Data2 = pathOfApk.Text; 
    info.Data3 = pathOfDec.Text; 
    info.Data4 = pathOfCom.Text; 
    info.Data5 = disableDebugChkBox.Checked.ToString(); 
    SaveXML.SaveData(info, docs + @"\cfg.xml"); 
} 

SaveXML.cs

using System.Xml.Serialization; 
using System.IO; 

namespace APK 
{ 
    public class SaveXML 
    { 
     public static void SaveData(object obj, string filename) 
     { 
      XmlSerializer sr = new XmlSerializer(obj.GetType()); 
      TextWriter writer = new StreamWriter(filename); 
      sr.Serialize(writer, obj); 
      writer.Close(); 
     } 
    } 
} 

Data.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace APK 
{ 
    public class Data 
    { 
     private string data1, data2, data3, data4, data5; 

     public string Data1 
     { 
      get { return data1; } 
      set { data1 = value; } 
     } 

     public string Data2 
     { 
      get { return data2; } 
      set { data2 = value; } 
     } 

     public string Data3 
     { 
      get { return data3; } 
      set { data3 = value; } 
     } 

     public string Data4 
     { 
      get { return data4; } 
      set { data4 = value; } 
     } 

     public string Data5 
     { 
      get { return data5; } 
      set { data5 = value; } 
     } 
    } 
} 
+0

行われているはい、あなたのストリームを閉じます。しかし、 '.Close()'コールの前に何か悪い(例外)が起きてファイルを閉じることを保証することはできますか? **いいえ**。例外を除いてシリアル化/逆シリアル化が失敗した場合、共有ストリーム違反のために他のファイル操作を妨げる、まだ開いているストリーム/ハンドルがあります。この場合に対処するには、[キーワードを使用する](http://stackoverflow.com/questions/567138/when-should-i-use-using-blocks-in-c)、または最後に手動でブロックします。 –

+0

Ttry From:SaveData(オブジェクトobj、string filename)To:SaveData(Data obj、string filename)なぜDataではなくobjectを使用していますか? – jdweng

+1

bool.Parse(info.Data5)を実行すると、info.Data5がnullの場合、例外が発生し、ファイルを閉じることはありません。あなたは "最後"ブロックでそれを行う必要があります。私がvar x = bool.Parse(null)を実行して "view dtails"に行くとき、私はまったく同じエラーを出しています: "値はnullではありません。 – derloopkat

答えて

1

多分これは、問題を解決しますが、read.close();read.EndRead();を置くそれともcatch声明でそれを閉じてみてくださいません。 しかしとしては、すでに言われては、最良の選択肢は、このようにそれを行うことです。

if (File.Exists(docs + @"\cfg.xml")) 
      { 
       try 
       { 
        using (FileStream read = new FileStream(docs + @"\cfg.xml", FileMode.Open, FileAccess.Read, FileShare.Read)){ 
         XmlSerializer xs = new XmlSerializer(typeof(Data)); 
         Data info = (Data)xs.Deserialize(read); 
         signApkCheckBox.Checked = bool.Parse(info.Data1); 
         pathOfApk.Text = info.Data2; 
         pathOfDec.Text = info.Data3; 
         pathOfCom.Text = info.Data4; 
         disableDebugChkBox.Checked = bool.Parse(info.Data5);    
        } 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.Message); 
       } 
      } 

あなたは文句を言わないで、すべてのファイルを閉じる心配する必要はこの道を、それが「自動的に」

+0

それが問題を解決しました – prouser135

関連する問題