我正在尝试读取文本文件(如果存在),然后在每行的开头搜索特定的字符串。如果它存在,我想用新输入的变量覆盖该行。单击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);
}
}
答案 0 :(得分:0)
正如我所看到的,您正在关闭现有应用程序上的所有流。您需要在使用它们后立即关闭它们。例如,一旦您将文件内容读取到阅读器,您就可以关闭文件流。同样,当您将阅读器流移动到编写器流时,您需要立即关闭阅读器流。
由于某些开放流,您肯定会发生上述错误。因此,为了确保文件不会以某种方式被其他进程访问,只需在使用它们时立即关闭它们。试试这个,如果需要进一步的帮助,请分享。