C# streamreader 和 streamwriter 到同一个文件
C# streamreader and streamwriter onto same file
如何读写同一个文件?
我的代码示例如下所示:
List<string> Data = new List<string>();
StreamReader sr = new StreamReader(@"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf");
StreamWriter sw = new StreamWriter(@"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf");
while ((line = sr.ReadLine()) != null)
{
Data.Add(line);
}
int budget = int.Parse(Data[1].Substring(15, 3));
for (int i = 0; i < Data.Count; i++)
{
if (Data[i] != "ENDE")
{
numb = rnd.Next(0, 7);
if (Data[i].Substring(0,1) == "0" || Data[i].Substring(0, 1) == "1" || Data[i].Substring(0, 1) == "2" || Data[i].Substring(0, 1) == "3" || Data[i].Substring(0, 1) == "4" || Data[i].Substring(0, 1) == "5" || Data[i].Substring(0, 1) == "6" || Data[i].Substring(0, 1) == "7")
{
betnumb = int.Parse(Data[i].Substring(0, 1));
betamount = int.Parse(Data[i].Split(' ') [1]);
if (betnumb == numb)
{
budget += betamount * 7;
}
else
{
budget -= betamount;
}
if (budget < 0)
{
sw.Write("Pleite");
Console.WriteLine("Pleite");
}
}
}
}
但我似乎无法读取和写入同一个文件,因为文件没有任何变化,从来没有。
也许有人知道我的问题是什么?
使用Flush to reflect the changes to file or set StreamWriter.AutoFlush = true
List<string> Data = new List<string>();
string path = @"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf"
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
StreamReader sr = new StreamReader(fs);
StreamWriter sw = new StreamWriter(fs);
while ((line=sr.ReadLine()) != null)
{
Data.Add(line);
}
int budget = int.Parse(Data[1].Substring(15, 3));
for (int i = 0; i < Data.Count; i++)
{
if (Data[i] != "ENDE")
{
numb = rnd.Next(0, 7);
if (Data[i].Substring(0,1) == "0" || Data[i].Substring(0, 1) == "1" || Data[i].Substring(0, 1) == "2" || Data[i].Substring(0, 1) == "3" || Data[i].Substring(0, 1) == "4" || Data[i].Substring(0, 1) == "5" || Data[i].Substring(0, 1) == "6" || Data[i].Substring(0, 1) == "7")
{
betnumb = int.Parse(Data[i].Substring(0, 1));
betamount = int.Parse(Data[i].Split(' ') [1]);
if (betnumb == numb)
{
budget+=betamount*7;
}
else
{
budget -= betamount;
}
if (budget < 0)
{
sw.Write("Pleite");
sw.Flush();
Console.WriteLine("Pleite");
}
}
}
}
您永远不会关闭 StreamWriter
。因此,新内容永远不会刷新,文件保持打开状态。将 StreamWriter
包含在 using
语句中,该语句会在末尾或每当剩下 using 块时自动刷新并关闭文件(也可能是因为 break
、return
或异常)。
如果您打算将数据附加到文件中,您可以使用 File.AppendText(Path)
创建编写器。
由于您在写入文件之前读取文件,因此在写入时保持 reader 打开是没有意义的。您甚至不需要创建 StreamWriter
。只需将整个文件读入数组 File.ReadAllLines(Path)
.
const string Path = @"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf";
string[] data = File.ReadAllLines(Path);
int budget = Int32.Parse(data[1].Substring(15, 3));
using (StreamWriter sw = File.AppendText(Path)) {
for (int i = 0; i < data.Length && data[i] != "ENDE"; i++) {
numb = rnd.Next(0, 7);
char digit = data[i][0]; // Take the 1st char instead of Substring(0,1).
if ('0' <= digit && digit <= '7') { // Chars can be compared like numbers.
betnumb = digit - '0'; // You can do math on chars.
betamount = Int32.Parse(data[i].Split(' ')[1]);
if (betnumb == numb) {
budget += betamount * 7;
} else {
budget -= betamount;
}
if (budget < 0) {
sw.Write("Pleite");
Console.WriteLine("Pleite"); // German for "bankrupt".
break; // Probably you don't want to continue looping when bankrupt.
}
}
}
} // Automatically flushes and closes the file here.
您可以进行的优化和更正很少。我猜您想在达到 "ENDE"
(德语表示 "end")时停止 for 循环。您可以通过将此条件添加到 for 循环条件来执行此操作:i < data.Length && data[i] != "ENDE"
.
可能你也不想在破产时继续循环(budget < 0
)。您可以使用 break;
退出循环。如果你这样做,也意味着你只写了一次文件。在这种情况下,您甚至可以简化文件编写。而不是使用 StreamWriter
:
using (StreamWriter sw = File.AppendText(Path)) {
...
sw.Write("Pleite");
...
}
...你可以简单地写:
File.AppendAllText(Path, "Pleite");
通过这种简化,代码变为:
const string Path = @"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf";
string[] data = File.ReadAllLines(Path);
int budget = Int32.Parse(data[1].Substring(15, 3));
for (int i = 0; i < data.Length && data[i] != "ENDE"; i++) {
numb = rnd.Next(0, 7);
char digit = data[i][0]; // Take the 1st char instead of Substring(0,1).
if ('0' <= digit && digit <= '7') { // Chars can be compared like numbers.
betnumb = digit - '0'; // You can do math on chars.
betamount = Int32.Parse(data[i].Split(' ')[1]);
if (betnumb == numb) {
budget += betamount * 7;
} else {
budget -= betamount;
}
if (budget < 0) {
File.AppendAllText(Path, "Pleite");
Console.WriteLine("Pleite");
break;
}
}
}
File
中的这些静态方法非常方便,因为它们在一条语句中读取或写入以及打开和关闭文件。
您可以简化第一个数字的范围测试。无需重复调用 data[i].Substring(0,1)
,只需将第一个字符存储为 char digit = data[i][0];
。字符的行为类似于整数。您可以比较它们 ('0' <= digit && digit <= '7'
) 并对其进行计算。 digit - '0'
获取数字的值为 int
.
我将文件路径存储在常量中,以避免重复。
局部变量和方法参数通常用驼峰式书写。因此我将 Data
重命名为 data
.
如何读写同一个文件?
我的代码示例如下所示:
List<string> Data = new List<string>();
StreamReader sr = new StreamReader(@"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf");
StreamWriter sw = new StreamWriter(@"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf");
while ((line = sr.ReadLine()) != null)
{
Data.Add(line);
}
int budget = int.Parse(Data[1].Substring(15, 3));
for (int i = 0; i < Data.Count; i++)
{
if (Data[i] != "ENDE")
{
numb = rnd.Next(0, 7);
if (Data[i].Substring(0,1) == "0" || Data[i].Substring(0, 1) == "1" || Data[i].Substring(0, 1) == "2" || Data[i].Substring(0, 1) == "3" || Data[i].Substring(0, 1) == "4" || Data[i].Substring(0, 1) == "5" || Data[i].Substring(0, 1) == "6" || Data[i].Substring(0, 1) == "7")
{
betnumb = int.Parse(Data[i].Substring(0, 1));
betamount = int.Parse(Data[i].Split(' ') [1]);
if (betnumb == numb)
{
budget += betamount * 7;
}
else
{
budget -= betamount;
}
if (budget < 0)
{
sw.Write("Pleite");
Console.WriteLine("Pleite");
}
}
}
}
但我似乎无法读取和写入同一个文件,因为文件没有任何变化,从来没有。
也许有人知道我的问题是什么?
使用Flush to reflect the changes to file or set StreamWriter.AutoFlush = true
List<string> Data = new List<string>();
string path = @"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf"
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
StreamReader sr = new StreamReader(fs);
StreamWriter sw = new StreamWriter(fs);
while ((line=sr.ReadLine()) != null)
{
Data.Add(line);
}
int budget = int.Parse(Data[1].Substring(15, 3));
for (int i = 0; i < Data.Count; i++)
{
if (Data[i] != "ENDE")
{
numb = rnd.Next(0, 7);
if (Data[i].Substring(0,1) == "0" || Data[i].Substring(0, 1) == "1" || Data[i].Substring(0, 1) == "2" || Data[i].Substring(0, 1) == "3" || Data[i].Substring(0, 1) == "4" || Data[i].Substring(0, 1) == "5" || Data[i].Substring(0, 1) == "6" || Data[i].Substring(0, 1) == "7")
{
betnumb = int.Parse(Data[i].Substring(0, 1));
betamount = int.Parse(Data[i].Split(' ') [1]);
if (betnumb == numb)
{
budget+=betamount*7;
}
else
{
budget -= betamount;
}
if (budget < 0)
{
sw.Write("Pleite");
sw.Flush();
Console.WriteLine("Pleite");
}
}
}
}
您永远不会关闭 StreamWriter
。因此,新内容永远不会刷新,文件保持打开状态。将 StreamWriter
包含在 using
语句中,该语句会在末尾或每当剩下 using 块时自动刷新并关闭文件(也可能是因为 break
、return
或异常)。
如果您打算将数据附加到文件中,您可以使用 File.AppendText(Path)
创建编写器。
由于您在写入文件之前读取文件,因此在写入时保持 reader 打开是没有意义的。您甚至不需要创建 StreamWriter
。只需将整个文件读入数组 File.ReadAllLines(Path)
.
const string Path = @"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf";
string[] data = File.ReadAllLines(Path);
int budget = Int32.Parse(data[1].Substring(15, 3));
using (StreamWriter sw = File.AppendText(Path)) {
for (int i = 0; i < data.Length && data[i] != "ENDE"; i++) {
numb = rnd.Next(0, 7);
char digit = data[i][0]; // Take the 1st char instead of Substring(0,1).
if ('0' <= digit && digit <= '7') { // Chars can be compared like numbers.
betnumb = digit - '0'; // You can do math on chars.
betamount = Int32.Parse(data[i].Split(' ')[1]);
if (betnumb == numb) {
budget += betamount * 7;
} else {
budget -= betamount;
}
if (budget < 0) {
sw.Write("Pleite");
Console.WriteLine("Pleite"); // German for "bankrupt".
break; // Probably you don't want to continue looping when bankrupt.
}
}
}
} // Automatically flushes and closes the file here.
您可以进行的优化和更正很少。我猜您想在达到 "ENDE"
(德语表示 "end")时停止 for 循环。您可以通过将此条件添加到 for 循环条件来执行此操作:i < data.Length && data[i] != "ENDE"
.
可能你也不想在破产时继续循环(budget < 0
)。您可以使用 break;
退出循环。如果你这样做,也意味着你只写了一次文件。在这种情况下,您甚至可以简化文件编写。而不是使用 StreamWriter
:
using (StreamWriter sw = File.AppendText(Path)) {
...
sw.Write("Pleite");
...
}
...你可以简单地写:
File.AppendAllText(Path, "Pleite");
通过这种简化,代码变为:
const string Path = @"C:\Users\manda\Desktop\Schule\Pos1\HüW2Casino\Spieler1.conf";
string[] data = File.ReadAllLines(Path);
int budget = Int32.Parse(data[1].Substring(15, 3));
for (int i = 0; i < data.Length && data[i] != "ENDE"; i++) {
numb = rnd.Next(0, 7);
char digit = data[i][0]; // Take the 1st char instead of Substring(0,1).
if ('0' <= digit && digit <= '7') { // Chars can be compared like numbers.
betnumb = digit - '0'; // You can do math on chars.
betamount = Int32.Parse(data[i].Split(' ')[1]);
if (betnumb == numb) {
budget += betamount * 7;
} else {
budget -= betamount;
}
if (budget < 0) {
File.AppendAllText(Path, "Pleite");
Console.WriteLine("Pleite");
break;
}
}
}
File
中的这些静态方法非常方便,因为它们在一条语句中读取或写入以及打开和关闭文件。
您可以简化第一个数字的范围测试。无需重复调用 data[i].Substring(0,1)
,只需将第一个字符存储为 char digit = data[i][0];
。字符的行为类似于整数。您可以比较它们 ('0' <= digit && digit <= '7'
) 并对其进行计算。 digit - '0'
获取数字的值为 int
.
我将文件路径存储在常量中,以避免重复。
局部变量和方法参数通常用驼峰式书写。因此我将 Data
重命名为 data
.