简体   繁体   中英

FileInfo.Length is greater than 0 but File is Empty?

I have an application that crunches a bunch of text files. Currently, I have code like this (snipped-together excerpt):

FileInfo info = new FileInfo(...)
if (info.Length > 0) {
    string content = getFileContents(...);
        // uses a StreamReader
        // returns reader.ReadToEnd();
    Debug.Assert(!string.IsNullOrEmpty(contents)); // FAIL
}

private string getFileContents(string filename)
    {
        TextReader reader = null;
        string text = "";

        try
        {
            reader = new StreamReader(filename);
            text = reader.ReadToEnd();
        }
        catch (IOException e)
        {
            // File is concurrently accessed. Come back later.
            text = "";
        }
        finally
        {
            if (reader != null)
            {
                reader.Close();
            }
        }

        return text;
    }

Why am I getting a failed assert? The FileInfo.Length attribute was already used to validate that the file is non-empty.

Edit: This appears to be a bug -- I'm catching IO exceptions and returning empty-string. But, because of the discussion around fileInfo.Length(), here's something interesting: fileInfo.Length returns 2 for an empty, only-BOM-marker text file (created in Notepad).

You might have a file which is empty apart from a byte-order mark. I think TextReader.ReadToEnd() would remove the byte-order mark, giving you an empty string.

Alternatively, the file could have been truncated between checking the length and reading it.

For diagnostic purposes, I suggest you log the file length when you get an empty string.

See that catch (IOException) block you have? That's what returns an empty string and triggers the assert even when the file is not empty.

If I remember well, a file ends with end of file, which won't be included when you call ReadToEnd.

Therefore, the file size is not 0, but it's content size is.

What's in the getFileContents method?

It may be repositioning the stream's pointer to the end of the stream before ReadToEnd() is called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM