简体   繁体   中英

C# streamreader and streamwriter onto same file

How do I read and write onto the same file?

A sample of my code looks like this:

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");
            }
        }
    }
}

But it seems like I can't read and write onto the same file, as there are no changes to the file, never.

Maybe anyone knows what my problem is?

Use 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");
           }
        }
    }
}

You never close the StreamWriter . Therefore the new content is never flushed and the file is kept open. Enclose the StreamWriter in a using -statement which automatically flushes and closes the file at the end or whenever the using block is left (can also be because of a break , a return or and exception).

If your intention is to append data to the file, you can create the writer with File.AppendText(Path) .

Since you read the file before you write to it, there is no point in keeping the reader open while writing. You don't even need to create a StreamWriter . just read the whole file into an array with 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.

There are few optimizations and corrections you can make. I guess that you want to stop the for-loop when "ENDE" (German for "end") is reached. You can do this by adding this condition to the for-loop-condition: i < data.Length && data[i] != "ENDE" .

Probably you also don't want to continue looping when bankrupt ( budget < 0 ). You can exit the loop with break; . If you do this, it also means that you only write once the file. In this case you can even simplify the file writing. Instead of using a StreamWriter :

using (StreamWriter sw = File.AppendText(Path)) {
    ...
    sw.Write("Pleite");
    ...
}

... you can simply write:

    File.AppendAllText(Path, "Pleite");

With this simplification the code becomes:

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;
        }
    }
}

These static methods in File are very handy, as they read or write and open and close the file in one single statement.

You can simplify the range test for the first digit. Instead of calling data[i].Substring(0,1) repeatedly, simply store the first character with char digit = data[i][0]; . Characters behave like integers. You can compare them ( '0' <= digit && digit <= '7' ) and perform calculation on them. digit - '0' gets the value of the digit as int .

I stored the file path in a constant, to avoid its repetition.

Local variables and method parameters are usually written in camelCase. Therefore I renamed Data as data .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM