c#阅读器文本文件,搜索字符串,覆盖行

本文关键字:搜索 字符串 覆盖 文件 文本 | 更新日期: 2023-09-27 18:15:40

我试图读取一个文本文件,如果它存在,然后在每行开头搜索一个特定的字符串。如果它存在,我想用新输入的变量覆盖这一行。当点击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);
        }
    }

c#阅读器文本文件,搜索字符串,覆盖行

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

你上面的错误肯定是由于某些打开的流而发生的。因此,为了确保文件不被其他进程访问,只需在使用流时立即关闭流。试试这个,如果需要进一步的帮助,请分享。