0

我正在尝试读取一个文本文件(如果存在),然后在每行的开头搜索一个特定的字符串。如果存在,我想用新输入的变量覆盖该行。Enter/Update Player单击按钮时出现错误。我已经在发生错误的代码中注明。

我收到的错误:

“该进程无法访问该文件,因为它正被另一个进程使用。”

我假设这与 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);
        }
    }
4

1 回答 1

0

如我所见,您正在关闭现有应用程序上的所有流。您需要在使用流后立即关闭它们。例如,一旦您将文件内容读取到阅读器,您就可以关闭文件流。同样,当您将读取器流移动到写入器流时,您需要立即关闭读取器流。

由于某些开放流,您的上述错误肯定会发生。因此,为了确保文件不会被其他进程以某种方式访问​​,只需在使用流后立即关闭它们。试试这个,如果需要进一步的帮助,请分享。

于 2013-05-27T04:13:55.940 回答