Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does FileInfo.Extension return the last *.* pattern, or something else?

I'm curious what exactly the behavior is on the following:

FileInfo info = new FileInfo("C:/testfile.txt.gz");
string ext = info.Extension;

Will this return ".txt.gz" or ".gz"?

What is the behavior with even more extensions, such as ".txt.gz.zip" or something like that?

EDIT:

To be clear, I've already tested this. I would like an explanation of the property.

like image 516
Codeman Avatar asked Oct 02 '12 17:10

Codeman


3 Answers

It will return .gz, but the explanation from MSDN (FileSystemInfo.Extension Property) isn't clear why:

"The Extension property returns the FileSystemInfo extension, including the period (.). For example, for a file c:\NewFile.txt, this property returns ".txt"."

So I looked up the code of the Extension property with reflector:

public string Extension
{
    get
    {
        int length = this.FullPath.Length;
        int startIndex = length;
        while (--startIndex >= 0)
        {
            char ch = this.FullPath[startIndex];
            if (ch == '.')
            {
                return this.FullPath.Substring(startIndex, length - startIndex);
            }
            if (((ch == Path.DirectorySeparatorChar) || (ch == Path.AltDirectorySeparatorChar)) || (ch == Path.VolumeSeparatorChar))
            {
                break;
            }
        }
        return string.Empty;
    }
}

It's check every char from the end of the filepath till it finds a dot, then a substring is returned from the dot to the end of the filepath.

like image 192
Erwin Avatar answered Nov 17 '22 11:11

Erwin


It returns the extension from the last dot, because it can't guess whether another part of the filename is part of the extension. In the case of testfile.txt.gz, you could argue that the extension is .txt.gz, but what about System.Data.dll? Should the extension be .Data.dll? Probably not... There's no way to guess, so the Extension property doesn't try to.

like image 7
Thomas Levesque Avatar answered Nov 17 '22 12:11

Thomas Levesque


[TestCase(@"C:/testfile.txt.gz", ".gz")]
[TestCase(@"C:/testfile.txt.gz.zip", ".zip")]
[TestCase(@"C:/testfile.txt.gz.SO.jpg", ".jpg")]
public void TestName(string fileName, string expected)
{
    FileInfo info = new FileInfo(fileName);
    string actual = info.Extension;
    Assert.AreEqual(actual, expected);
}

All pass

like image 10
Johan Larsson Avatar answered Nov 17 '22 12:11

Johan Larsson