2015-10-07 73 views
0

我在form application中有一個文本文件installer_input.txt和一個checkedListBox2。我想編輯文本文件,如果我在checkesListBox2有一些變化。我有兩個代碼部分,我知道,這麼長,但我需要一些幫助:我編輯後如何關閉文本文件?

private void checkedListBox2_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      string path = AppDomain.CurrentDomain.BaseDirectory.ToString(); 
      var lin = (path + "config.ini").ToString(); 
      var lines = File.ReadAllLines(lin); 
      string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile=")) 
         .Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault(); 
      string pathTemp = @"C:\temp\"; 
      string[] pathArr = InstallerFile.Split('\\'); 
      string[] fileArr = pathArr.Last().Split('\\'); 
      string fileArr1 = String.Join(" ", fileArr); 


      string installerfilename = string.Format("{0}{1}", pathTemp, fileArr1); 
      IEnumerable<string> inilines = File.ReadAllLines(installerfilename).AsEnumerable(); 
      bool IsChecked = checkedListBox2.CheckedItems.Contains(checkedListBox2.SelectedItem); 
else if (fileArr1.Equals("installer_input.txt")) 
      { 
       if (IsChecked && checkedListBox2.CheckedItems.Count != checkedListBox2.Items.Count) 
        inilines = inilines.Select(line => line == string.Format("#product.{0}", checkedListBox2.SelectedItem) 
                 ? Regex.Replace(line, string.Format("#product.{0}", checkedListBox2.SelectedItem), string.Format(@"product.{0}", checkedListBox2.SelectedItem)) 
                 : line); 
       else if (!IsChecked || checkedListBox2.CheckedItems.Count == checkedListBox2.Items.Count) 
        inilines = inilines.Select(line => (line == string.Format("product.{0}", checkedListBox2.SelectedItem)) 
                 ? Regex.Replace(line, string.Format(@".*product.{0}", checkedListBox2.SelectedItem), string.Format(@"#product.{0}", checkedListBox2.SelectedItem)) 
                 : line); 
       if (checkedListBox2.CheckedItems.Count == checkedListBox2.Items.Count) 
        checkBox1.Checked = true; 

       else 
        checkBox1.Checked = false; 

       string strWrite = string.Join(Environment.NewLine, inilines.ToArray()); 
       File.WriteAllText(installerfilename, strWrite); 

      } 
     } 

和第二代碼是:

private void checkBox1_CheckedChanged_1(object sender, EventArgs e) 
     { 
      CheckBox cb = sender as CheckBox; 
      SetAllItemsChecked(cb.Checked); 

      var installerLines = ReadInstallerLines(); 
      SetAllProductsChecked(installerLines.ToList(), cb.Checked); 
      SaveInstaller(installerLines); 
     } 

     private void SetAllItemsChecked(bool check) 
     { 
      for (int i = 0; i < this.checkedListBox2.Items.Count; i++) 
      { 
       this.checkedListBox2.SetItemChecked(i, check); 
      } 
     } 

     private IEnumerable<string> ReadInstallerLines() 
     { 
      var lin = (path + "config.ini").ToString(); 
      var lines = File.ReadAllLines(lin); 
      string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile=")) 
         .Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault(); 
      string pathTemp = @"C:\temp\"; 
      string[] pathArr = InstallerFile.Split('\\'); 
      string[] fileArr = pathArr.Last().Split('\\'); 
      string fileArr1 = String.Join(" ", fileArr); 
      string installerfilename = pathTemp + fileArr1; 
      string installertext = File.ReadAllText(installerfilename); 
      return File.ReadLines(pathTemp + fileArr1); 
     } 

     private void SetAllProductsChecked(IList<string> installerLines, bool check) 
     { 
      for (var i = 0; i < installerLines.Count; i++) 
      { 
       if (installerLines[i].Contains("product=")) 
       { 
        installerLines[i] = check 
         ? installerLines[i].Replace("#product", "product") 
         : installerLines[i].Replace("product", "#product"); 
       } 
       if (installerLines[i].Contains("product.")) 
       { 
        installerLines[i] = check 
         ?installerLines[i].Replace("#product.", "product.") 
         : installerLines[i].Replace("product.", "#product."); 
       } 
      } 
     } 

     private void SaveInstaller(IEnumerable<string> installerLines) 
     { 
      var lin = (path + "config.ini").ToString(); 
      var lines = File.ReadAllLines(lin); 
      string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile=")) 
         .Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault(); 
      string pathTemp = @"C:\temp\"; 
      string[] pathArr = InstallerFile.Split('\\'); 
      string[] fileArr = pathArr.Last().Split('\\'); 
      string fileArr1 = String.Join(" ", fileArr); 
      string installerfilename = pathTemp + fileArr1;   
      File.WriteAllLines(installerfilename, installerLines); 
     } 
    } 

第一部作品,我可以從檢查盒列表,但是當我嘗試點擊checkBox1時,我有下一個錯誤:The process cannot access the file 'C:\temp\installer_input.txt' because it is used by another process。 如何讓程序運行?我如何優化我的代碼?

+0

嘗試使用'File.ReadAllLines'而不是'File.ReadLines'。 –

+0

Wouu ...非常感謝!你可以幫我理解優化嗎? – uid

+2

不,如果代碼正常工作,但您認爲它可以/應該優化,請在[codereview](http://codereview.stackexchange.com)上重新發布工作代碼並尋求幫助。 –

回答

0

基本上單個線程/進程可以訪問的資源是在一個情況下,你所能做的就是用EventWaitHandle等待,直到其他進程或線程什麼在這種情況下,該文件已佔據該文件是這樣的:

EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES"); 
waitHandle.WaitOne(); 
/* process file*/ 
waitHandle.Set();