IO Exception - a file in use by another process (cannot open file after directory creation)

I have an on-the-go project that monitors vet patients while they are working and writes the result to a text file. While I was experimenting with the pins, I just left the files in the Debug folder that worked fine. However, I have now created a full directory that creates or opens the main folder and then a sub folder (based on text input from the program) to save the text file.

    private void createDirectory()
    { //create output file in this folder using owner name and current date

        //main folder path (contains all files output from system)
        string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Horse Monitoring Records";
        //sub folder path (each patient has individual subfolder)
        string subDirectory = rootDirectory + "\\" + txtPatName.Text + "-" + txtOwnerName.Text;
        //file name (patient has file created for each operation)
        fileName = subDirectory +  "\\" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("ddMMyyyy") + ".txt";

        if (!Directory.Exists(rootDirectory)) //if main folder does not exist...
        {
            Directory.CreateDirectory(rootDirectory); //create it in My Documents
        }
        if (!Directory.Exists(subDirectory)) //if patient sub folder does not exist...
        {
            Directory.CreateDirectory(subDirectory); //create it in Patient-Owner format
        }
        if (!File.Exists(fileName)) //if monitoring file does not exist...
        {
            File.Create(fileName); //create it in Owner-Date format
        }
    }

      

This step works fine, but as soon as you try to store some data in a text file, it throws a runtime error stating that

The file cannot be accessed because it is being used by another process.

Here's the exception:

    private void saveFileDetails()
    {
        //Once case details have been entered, create new file using these details and add data input structure
        StreamWriter consoleFile = new StreamWriter(fileName);
    ...
    }

      

When I went and checked the folder, the corresponding subfolder and file was created, but the text file was empty. I am guessing it has to do with closing the text file after the directory has been created, which means it is already open when the system tries to open it. I can't figure out how to sort this issue though!

The above two functions are named like this:

    private void btnStart_Click(object sender, EventArgs e)
    {
        ...

        //file details entered upon load written to new file - according to PatID
        createDirectory();
        saveFileDetails();
    }

      

Any suggestions on where to go from here would be greatly appreciated!

Thanks Mark

+3


source to share


3 answers


The problem is what you do

if (!File.Exists(fileName)) //if monitoring file does not exist...
{
    File.Create(fileName); //create it in Owner-Date format
}

      

Before trying to write to a file. Since you just created it (if it didn't exist), chances are the operating system hasn't released the file yet.

Similar to @Jauch mentioned in the comments, you can skip this check entirely and use an overload StreamWriter

that will create the file if it doesn't exist, or add to it if it does.



private void saveFileDetails()
{
    //Once case details have been entered, create new file using these details and add data input structure
    using (StreamWriter consoleFile = new StreamWriter(fileName, true))
    {
        // ...
    }
}

      

Alternatively, you can use the following to write the entire text at once:

File.AppendAllText(textToWrite, fileName);

      

+1


source


File.Create(fileName)

returns an open stream to a file that is never closed.

To create an empty file use File.WriteAllBytes(fileName, new byte[0]);

Otherwise 2 methods can be shortened



private void SaveFileDetails()
{
    string subDirectory = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
        "Horse Monitoring Records");

    // create the folder hierarchy if not exists. does nothing if already there
    Directory.CreateDirectory(subDirectory);

    // each patient has individual file
    var filepath = Path.Combine(subDirectory,
        txtPatName.Text + "-" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt");

    // creates the file if not exists
    using (var writer = new StreamWriter(filepath, append: true, encoding: Encoding.UTF8))
    {
        // write details
    }
}

      

Note:

  • combined 2 methods
  • .NET naming conventions used
  • changed date format to sort better by name in explorer
+1


source


StreamWriter

implements IDisposable

, so using it in a use block can manage the closing and deletion of a record and ensure that it is available the next time you want to touch that file. It can also control the creation of a text file if it doesn't exist, eliminating the need for an explicit call File.Create

.

StreamWriter consoleFile = new StreamWriter(fileName);

      

becomes

using (StreamWriter writer = File.AppendText("log.txt"))
{
    // writing, etc.
}

      

or

using (StreamWriter writer = new StreamWriter(fileName, true))
{ // true says "append to file if it exists, create if it doesn't"
    // writing, etc.
}

      

Anything that seems more readable to you works great.

0


source







All Articles