2013-05-27 72 views
0

我試圖讀取文本文件,如果它存在,然後搜索每行開頭的特定字符串。如果存在,我想用新輸入的變量覆蓋那一行。單擊Enter/Update Player按鈕時出現錯誤。我在代碼中注意到發生錯誤的位置。C#讀取文本文件,搜索字符串,覆蓋行

錯誤我收到:

「的過程不能因爲它是被另一個進程 訪問文件。」

我假設這是有關的StreamReader/StreamWriter的干擾,但我無法弄清楚錯誤來自哪裏。任何幫助將不勝感激!

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Runtime.Serialization; 
using System.Text; 
using System.Windows.Forms; 

namespace Namespace1 
{ 
    public partial class FormPokerStats : Form // FormPokerStats inheriting from class Form 
    { 
     // declaring and assigning of variables needed for file read/write 
     const char DELIM = ','; 
     const string FILEPATH = @"C:\C# Project Output\"; 
     const string FILENAME = "PokerPlayers.txt"; 

     // declaring instances of Person, Location, and Winnings classes 
     Location mycasino = new Location(); 
     Winnings mywinnings = new Winnings(); 

     public delegate void Total(double[] total); 

     // constructing in/out FileStream/StreamReader/StreamWriter objects 
     static FileStream inFile = new FileStream(FILEPATH + FILENAME, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite); 
     StreamWriter writer = new StreamWriter(outFile); 
     static FileStream outFile = new FileStream(FILEPATH + FILENAME, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); 
     StreamReader reader = new StreamReader(inFile); 

     public FormPokerStats() 
     { 
      InitializeComponent(); 
     } 

     // "Enter/Update Player" tab Enter Player button: read/assign user input, write to file, close file stream 
     private void buttonEnterPlayer_Click(object sender, EventArgs e) 
     { 
      Player myplayer = null; 

      // if directory does not exist, create it 
      if (!(Directory.Exists(FILEPATH))) 
      { 
       // create directory 
       Directory.CreateDirectory(FILEPATH); 
      } 

      try 
      { 
       // read user input and assign to variables; test for empty player inputs and reprompt for input, if necessary 
       // Player Information fields 
       // if any or all textboxes are left blank 
       if ((maskedTextBoxSSN.Text == String.Empty || textBoxFirstName.Text == String.Empty || textBoxLastName.Text == String.Empty 
        || textBoxCasinoName.Text == String.Empty || textBoxCasinoState.Text == String.Empty) || 
        (maskedTextBoxSSN.Text == String.Empty && textBoxFirstName.Text == String.Empty && textBoxLastName.Text == String.Empty 
        && textBoxCasinoName.Text == String.Empty && textBoxCasinoState.Text == String.Empty)) 
       { 
        MessageBox.Show("Please complete all player information fields.", "Input Error!"); 
       } 
       else 
       { 
        // if all textboxes are completed, assign to variables 
        myplayer = new Player(maskedTextBoxSSN.Text, textBoxFirstName.Text, textBoxLastName.Text); 
        mycasino.CasinoName = textBoxCasinoName.Text; 
        mycasino.CasinoState = textBoxCasinoState.Text; 
       } 

       // read weekly winnings input and assign to appropriate array position; test for empty inputs and assign default value of 0 if empty 
       // Week1 
       if (textBoxWeek1Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(0, 0); 
       } 
       else mywinnings.AddNewWinnings(0, Convert.ToDouble(textBoxWeek1Winnings.Text)); 

       // Week2 
       if (textBoxWeek2Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(1, 0); 
       } 
       else mywinnings.AddNewWinnings(1, Convert.ToDouble(textBoxWeek2Winnings.Text)); 

       // Week3 
       if (textBoxWeek3Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(2, 0); 
       } 
       else mywinnings.AddNewWinnings(2, Convert.ToDouble(textBoxWeek3Winnings.Text)); 

       // Week4 
       if (textBoxWeek4Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(3, 0); 
       } 
       else mywinnings.AddNewWinnings(3, Convert.ToDouble(textBoxWeek4Winnings.Text)); 

       // Week5 
       if (textBoxWeek5Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(4, 0); 
       } 
       else mywinnings.AddNewWinnings(4, Convert.ToDouble(textBoxWeek5Winnings.Text)); 

       // Week6 
       if (textBoxWeek6Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(5, 0); 
       } 
       else mywinnings.AddNewWinnings(5, Convert.ToDouble(textBoxWeek6Winnings.Text)); 

       // Week7 
       if (textBoxWeek7Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(6, 0); 
       } 
       else mywinnings.AddNewWinnings(6, Convert.ToDouble(textBoxWeek7Winnings.Text)); 

       // Week8 
       if (textBoxWeek8Winnings.Text == String.Empty) 
       { 
        mywinnings.AddNewWinnings(7, 0); 
       } 
       else mywinnings.AddNewWinnings(7, Convert.ToDouble(textBoxWeek8Winnings.Text)); 

       // calculate total winnings by summing WeeklyWinnings array values and assigning to TotalWinnings 
       Total pointer = null; 
       pointer += new Total(mywinnings.compileTotal); 
       pointer(mywinnings.WeeklyWinnings); 

       ///////////////////////////////////ERROR HERE//////////////////////////////////// 

       // check file for input SSN; if exists, overwrite that record and rewrite to file 
       if (!(File.Exists(FILEPATH + FILENAME))) 
       { 
        List<string> lines = new List<string>(File.ReadAllLines(FILEPATH + FILENAME)); 

        int lineIndex = lines.FindIndex(line => line.StartsWith(myplayer.SocialSecurityNumber)); 

        if (lineIndex != -1) 
        { 
         lines[lineIndex] = myplayer.ToString() + mycasino.ToString() + mywinnings.ToString(); 
         File.WriteAllLines(FILEPATH + FILENAME, lines); 
        } 
        else 
        { 
         // writing record to text file 
         writer.WriteLine(myplayer.ToString() + mycasino.ToString() + mywinnings.ToString()); 
        } 
       } 

       // if record is successfully written, display messagebox 
       MessageBox.Show("Wrote " + myplayer.FirstName.ToString() + ' ' + myplayer.LastName.ToString() + " to file with winnings totaling " + mywinnings.TotalWinnings.ToString("C2") + ".", "File Written"); 
      } 
      catch (FormatException) 
      { 
       // if format exception is thrown in try, display messagebox with message 
       MessageBox.Show("Winnings must be entered at xx.xx (e.g. 34.56).", "Input Error!"); 
      } 
      catch (Exception f) 
      { 
       // if exception is thrown in try, display messagebox with message 
       MessageBox.Show(f.Message, "Error!"); 
      } 

      // clear form textboxes 
      ClearTextBoxes(); 
      maskedTextBoxSSN.Clear(); 
      writer.Close(); 
     } 

     // "Enter/Update Player" tab Exit button: closes file streams and quits the application 
     private void buttonExit_Click(object sender, EventArgs e) 
     { 
      // closing file streams 
      reader.Close(); 
      inFile.Close(); 
      writer.Close(); 
      outFile.Close(); 

      // close application 
      Application.Exit(); 
     } 

     // "Player List" tab View Player Winnings button: read file records, display records sorted by total winnings descending 
     private void buttonRead_Click(object sender, EventArgs e) 
     { 
      // clear listbox items 
      listBoxOutputRecords.Items.Clear(); 

      // if file exists 
      if (!(File.Exists(FILEPATH + FILENAME))) 
      { 
       // if file does not exist, display messagebox 
       MessageBox.Show("File does not exist.", "File Does Not Exist!"); 
      } 
      else 
      { 
       string[] fields; 

       // output header row labels to listbox 
       listBoxOutputRecords.Items.Add("First Name\tLast Name\tCasino Name\tCasino State\tTotal Winnings\t"); 

       // read first record in file 
       string recordIn = reader.ReadLine(); 

       // instantiate an instance of playerList list of tuples 
       List<Tuple<string, string, string, string, double>> playerList = new List<Tuple<string, string, string, string, double>>(); 

       // loop through text file records until last record is reached 
       while (recordIn != null) 
       { 
        // split record into array and assign 
        fields = recordIn.Split(DELIM); 
        Player myplayer = new Player(fields[0], fields[1], fields[2]); 
        mycasino.CasinoName = fields[3]; 
        mycasino.CasinoState = fields[4]; 
        mywinnings.TotalWinnings = Convert.ToDouble(fields[13]); 

        // add player to the playerList list of tuples 
        playerList.Add(new Tuple<string, string, string, string, double>(myplayer.FirstName, myplayer.LastName, mycasino.CasinoName, mycasino.CasinoState, mywinnings.TotalWinnings)); 

        // read next record in file 
        recordIn = reader.ReadLine(); 
       } 

       // sort playerList list of tuples by total winnings descending 
       playerList.Sort((a, b) => b.Item5.CompareTo(a.Item5)); 

       // display each record of the playerList list of tuples in the listbox 
       foreach (var element in playerList) 
       { 
        listBoxOutputRecords.Items.Add(element.Item1 + "\t\t" + element.Item2 + "\t\t" + element.Item3 + "\t\t" + element.Item4 + "\t\t" + element.Item5.ToString("C2")); 
       } 
      } 

      // return file position to 0 
      inFile.Seek(0, SeekOrigin.Begin); 
     } 

     // "Player List" tab Exit button: call buttonExit_Click method 
     private void buttonExit2_Click(object sender, EventArgs e) 
     { 
      // call buttonExit_Click method 
      buttonExit_Click(sender, e); 
     } 

     // method to clear listbox items when "Player List" tab is left 
     private void tabPagePlayerList_Leave(object sender, EventArgs e) 
     { 
      // clear listbox items 
      listBoxOutputRecords.Items.Clear(); 
     } 

     // method to clear textbox controls 
     private void ClearTextBoxes() 
     { 
      Action<Control.ControlCollection> func = null; 

      func = (controls) => 
      { 
       foreach (Control control in controls) 
        if (control is TextBox) 
         (control as TextBox).Clear(); 
        else 
         func(control.Controls); 
      }; 

      func(Controls); 
     } 
    } 
+0

是因爲你正在讀寫同一個文件嗎?嘗試先使用臨時文件寫入。 – ysrb

回答

0

正如我所看到的,您正在關閉現有應用程序中的所有流。一旦你使用它們,你需要關閉流。例如,一旦您將文件內容讀取到閱讀器,您可以關閉文件流。同樣,當您將閱讀器流移動到編寫器流時,您需要立即關閉閱讀器流。

你的上述錯誤肯定是由於一些開放流。因此爲了確保文件不會被另一個進程訪問,只要在使用它們時儘快關閉它們。試試這個,如果需要進一步的幫助,請分享。