Zinconium
Zinconium

Reputation: 23

How to close file that has been read

So im trying to close a file (transactions.txt) that has been open that i've used to read into a textbox and now I want to save back to the file but the problem debug says that the file is in use so I need to find a way to close it. Can anyone help me with this? Thanks!

        SearchID = textBox1.Text;
        string ID = SearchID.ToString();
        bool idFound = false;
        int count = 0;

        foreach (var line in File.ReadLines("transactions.txt"))
        {

            //listView1.Items.Add(line);

            if (line.Contains(ID))
            {
                idFound = true;
            }

            //Displays Transactions if the variable SearchID is found.
            if (idFound && count < 8)
            {
                textBox2.Text += line + "\r\n";
                count++;

            }
        }
    }

    private void SaveEditedTransaction()
    {
        SearchID = textBox1.Text;
        string ID = SearchID.ToString();
        bool idFound = false;
        int count = 0;

        foreach (var lines in File.ReadLines("transactions.txt"))
        {

            //listView1.Items.Add(line);

            if (lines.Contains(ID))
            {
                idFound = true;
            }

            if (idFound)
            {
                string edited = File.ReadAllText("transactions.txt");
                edited = edited.Replace(lines, textBox2.Text);
                File.WriteAllText("Transactions.txt", edited);
            }

Upvotes: 1

Views: 21331

Answers (4)

Alessandro D&#39;Andria
Alessandro D&#39;Andria

Reputation: 8878

You can try with this:

File.WriteAllLines(
    "transactions.txt",
    File.ReadAllLines("transactions.txt")
        .Select(x => x.Contains(ID) ? textBox2.Text : x));

It works fine, but if the file is big you have to find other solutions.

Upvotes: 1

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391724

The problem here is that File.ReadLines keeps the file open while you read it, since you've put the call to write new text to it inside the loop, the file is still open.

Instead I would simply break out of the loop when you find the id, and then put the if-statement that writes to the file outside the loop.

This, however, means that you will also need to maintain which line to replace in.

So actually, instead I would switch to using File.ReadAllLines. This reads the entire file into memory, and closes it, before the loop starts.

Now, pragmatic minds might argue that if you have a lot of text in that text file, File.ReadLines (that you're currently using) will use a lot less memory than File.ReadAllLines (that I am suggesting you should use), but if that's the case then you should switch to a database, which would be much more suited to your purpose anyway. It is, however, a bit of an overkill for a toy project with 5 lines in that file.

Upvotes: 8

Oscar
Oscar

Reputation: 13990

You can use the StreamReader class instead of the methods of the File class. In this way you can use, Stream.Close() and Stream.Dispose().

Upvotes: 0

Lloyd
Lloyd

Reputation: 29668

Use StreamReader directly with the using statement, for example:

var lines = new List<string>();

using (StreamReader reader = new StreamReader(@"C:\test.txt")) {
    var line = reader.ReadLine();

    while (line != null) {
        lines.Add(line);
        line = reader.ReadLine();
    }
}

By using the using statement the StreamReader instance will automatically be disposed of after it's done with it.

Upvotes: 1

Related Questions