0

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;
    }
Richard Barker
  • 1,161
  • 2
  • 12
  • 30
  • Don.t use the `.Exists()` methods like that. Instead, handle the exception if the file is not there when you expect. – Joel Coehoorn May 12 '14 at 18:27
  • @Joel Coehoorn, and why is that? – tatigo May 12 '14 at 18:42
  • 1
    @tatigo Written about permissions, but the same logic applies to file existence, especially the last paragraph: http://stackoverflow.com/a/265958/3043 – Joel Coehoorn May 12 '14 at 18:48
  • @Joel, Its those kinds of answers that makes me come to stack overflow. Its those kinds of answers that give other more inexperienced developers wisdom. Thank you for the link! – Richard Barker May 12 '14 at 19:02

2 Answers2

2

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

Steve
  • 213,761
  • 22
  • 232
  • 286
0

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()) 
{
....
}
tatigo
  • 2,174
  • 1
  • 26
  • 32