Question

The error always pops up only after I create the file and then try to read from the new file. I know why it's erring (the file must still be open); but I'm lost as to how to fix this issue because FileInfo doesn't have a close method and there shouldn't be a stream on the file. There obviously must be a better way of coding this. Any help would be appreciated.

Code explained: the constructor builds the data I need, checks for and creates (if needed) the directory and files. after the constructor is finished, I call CheckHasData on each each FileInfo in the array; this is when the error occurs.

public FileHandler()
    {
        files = new FileInfo[fileNames.Count()];

        if (!Directory.Exists(stdDataPath))
        {
            Directory.CreateDirectory(stdDataPath);
        }
        filePaths = new string[fileNames.Length];
        for (int i = 0; i < fileNames.Length; i++)
        {
            this.filePaths[i] = stdDataPath + this.fileNames[i];
            this.files[i] = new FileInfo(filePaths[i]);
        }
        //check for data in each file
        checkAndMakeFiles();

    }
 private void checkAndMakeFiles()
    {
        foreach (FileInfo fI in this.files)
        {
            try
            {
                if (!fI.Exists)
                {
                    fI.Create();
                }
                fI.Refresh();
            }
            catch (FileNotFoundException e)
            {
                System.Windows.Forms.MessageBox.Show("File not found: " + e.FileName, "error", System.Windows.Forms.MessageBoxButtons.OK);
            }
            catch (FileLoadException e)
            {
                System.Windows.Forms.MessageBox.Show("File failed to load : " + e.FileName + "\nReason: " + e.Message, "error", System.Windows.Forms.MessageBoxButtons.OK);
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("error: " + e.GetType() + "\nReason" + e.Message + "\n" + e.StackTrace, "error", System.Windows.Forms.MessageBoxButtons.OK);
            }
        }
    }


private bool checkHasData(FileInfo fi)
    {
        FileStream fs = fi.OpenRead();
        bool data = fs.Length > 0 ? true : false;
        fs.Close();
        return data;
    }
Was it helpful?

Solution

Because FileInfo.Create opens a stream and you don't close it

 using(fI.Create())
     ;

Enclosing the call inside a using statement, also if empty, will ensure that the stream created by the call is closed and disposed

OTHER TIPS

The method Create() on the FileInfo returns FileStream, which should be closed after use.

Try this:

private void checkAndMakeFiles()
    {
        foreach (FileInfo fI in this.files)
        {
                if (!fI.Exists)
                {
                    fI.Create();
                    fI.Close();
                }
          }
    }

As a side note, whenever you deal with streams better use using so you won't need to manage the resource. for example:

using (FileStream fs = fi.Create()) 
{
....
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top