1

I am making simple text editor and got problems with saving. So I have 2 codes for saving, one is to save file using button and another ctrl+s keyboard shortcut, when saving with button everything works perfectly, but when i save with shortcut i get this error:

"process cannot access file because it's used by another process"

here is my code for button save: `

        saveFileDialog1.FileName = currentname;

        if (saveFileDialog1.ShowDialog() == DialogResult.OK)
        {

            StreamWriter writer = new StreamWriter(saveFileDialog1.OpenFile());

            writer.WriteLine(richTextBox1.Text);

            writer.Dispose();
            writer.Close();

            //so i have tabs in my editor so user can switch between them.
            //and this is the only way i found which tab is opened now.
            for (int i = 0; i < labels.Count; i++)
            {
               //i created new class that holds some variables including "isUsed" 
               //and Label itself.
                if (labels[i].isUsed)
                {
                    labels[i].Text = Path.GetFileName(saveFileDialog1.FileName);
                    labels[i].setText(labels[i].Text);
                    labels[i].path = saveFileDialog1.FileName;
                    break;
                }
            }

        }`

script above works normally, but the script below doesn't:

        public void save(){

        bool found = false;
       //that is class i made.
        AdvancedLabel label = new AdvancedLabel();

        //I hold all tabs in "Labels" List.
        for (int i = 0; i < labels.Count; i++)
        {
           //so if loop found the tab that is opened now...
            if (labels[i].isUsed)
            {
                label = labels[i];
                found = true;
                break;
             }
        }
        if (found)
        {
            try
            {

                label.label.Text.Remove(label.label.Text.Length - 1);

                //here i always get this error.
                StreamWriter writer = new StreamWriter(label.path);

                writer.WriteLine(richTextBox1.Text);
                label.setText(label.Text.Remove(label.Text.Length - 1));
                writer.Dispose();
                writer.Close();

            }
            catch (Exception e)
            {
                status.Text = "status: " + e.Message + ". Failed to save :(";

            }
        }
    }

Here is the full error:

An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file 'C:\Users\nika\Desktop\dd.html' because it is being used by another process.

EDIT:

thanks to you all guys, as i understood i should be using "using" statement and here is waht i came up with:

enter image description here

I forgot to mention that i am also opening file using stramreader. I changed it to "Using" statement but same things happen, even tho i am now using: File.appendalltext statement. This also works, but only if i save with button.

here is how i changed it (file opener not writers): `

          using (var sr = new StreamReader(openFileDialog1.FileName))
            {
                bool found = false;

                for (int i = 0; i < labels.Count; i++)
                {
                    if (labels[i].path == openFileDialog1.FileName)
                    {
                        found = true;

                        break;
                    }
                }
                if (!found)
                {

                    richTextBox1.Text = "";
                    richTextBox1.Text = sr.ReadToEnd();

                    spawnLabel();
                }
            }`

ps(this sounds so stupid)

as @GauravKP suggested:

enter image description here

any help will be appreciated! thanks!

--Nick.

Nick
  • 455
  • 9
  • 28
  • 1
    So what's the error you actually get ? – Jim Oct 05 '16 at 17:07
  • @Jim An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll Additional information: The process cannot access the file 'C:\Users\nika\Desktop\dd.html' because it is being used by another process. – Nick Oct 05 '16 at 17:09
  • why downvote? at least explain so i don't do this type of mistake in future!!! – Nick Oct 05 '16 at 17:11
  • 1
    In theory `StreamWriter` will close underlying stream but just in case try to store the result of `saveFileDialog1.OpenFile()` into a separated variable and close it after closing `writer`. BTW, you should take a look to `using` statement, more clear and safe than manually disposing – Claudio Redi Oct 05 '16 at 17:11
  • 2
    Possible duplicate of [IOException: The process cannot access the file 'file path' because it is being used by another process](http://stackoverflow.com/questions/26741191/ioexception-the-process-cannot-access-the-file-file-path-because-it-is-being) – Jim Oct 05 '16 at 17:12
  • 2
    There may be other parts of your program keeping the file open. Unless you got an exception, your original code should've closed the file just fine, though yes, use the `using` syntax to have more of a guarantee that this happens. Do you read/write the file elsewhere? – Lasse V. Karlsen Oct 05 '16 at 17:41
  • @LasseV.Karlsen hey, i will update my question to give more info. – Nick Oct 05 '16 at 17:46
  • Please include all relevant code and errors as text (not images) in the question itself. Also, when you edit your question like this, adding another question, you are making the current answers "wrong", which is considered bad form on SO. If you have an additional question to ask, ask a new question. See [ask]. – Heretic Monkey Oct 05 '16 at 17:56
  • Could you please print label.path? – Pavan Chandaka Oct 05 '16 at 17:59
  • @PavanChandaka here you go: C:\Users\nika\Desktop\tst.html – Nick Oct 05 '16 at 18:39
  • I suggest you to stop using `Stream` or `StreamWriter`, and use `File.ReadAllText` and `File.WriteAllText` instead. – Thariq Nugrohotomo Oct 11 '16 at 12:09

1 Answers1

1

Always use "using" when you are dealing with stream objects.

using (var stream = ...)
{
    /* code */

    stream.Close();
}

This is what documentation says:

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way.

The correct way is a key word here.

Because even though we call Dispose , "there is always a danger that the unmanaged resources will not be released, because the consumer of an object fails to call its Dispose method. "

Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
  • did i get this right? ` using (var writer = new StreamWriter(label.path)) { writer.WriteLine(richTextBox1.Text); label.setText(label.Text.Remove(label.Text.Length - 1)); writer.Close(); }` – Nick Oct 05 '16 at 17:29
  • Yes. You do not need to call "writer.close()" again. Using will take care of it. – Pavan Chandaka Oct 05 '16 at 17:32
  • 1
    @Nick You could simplify the code even more and just do [`File.AppendAllText(label.path, richTextBox1.Text);`](https://msdn.microsoft.com/en-us/library/ms143356(v=vs.110).aspx) and get rid of the StreamWriter entirely. – Scott Chamberlain Oct 05 '16 at 17:32
  • @ScottChamberlain hi! thanks for your comment i tried it and get same results, at least code looks cleaner and smaller! thanks anyways! – Nick Oct 05 '16 at 17:39
  • Could you please print label.path on console and see if the path is as expected? – Pavan Chandaka Oct 05 '16 at 18:07
  • @PavanChandaka yes everything is ok with path – Nick Oct 05 '16 at 18:39
  • Are you doing any sort of "File" operations on it.. ex: open/create or check existence etc.. – Pavan Chandaka Oct 05 '16 at 20:02