31

I am using fs.Length, where fs is a FileStream.

Is this an O(1) operation? I would think this would just read from the properties of the file, as opposed to going through the file to find when the seek position has reached the end. The file I am trying to find the length of could easily range from 1 MB to 4-5 GB.

However I noticed that there is a FileInfo class, which also has a Length property.

Do both of these Length properties theoretically take the same amount of time? Or does is fs.Length slower because it must open the FileStream first?

jpints14
  • 1,361
  • 6
  • 15
  • 24

2 Answers2

43

The natural way to get the file size in .NET is the FileInfo.Length property you mentioned.

I am not sure Stream.Length is slower (it won't read the whole file anyway), but it's definitely more natural to use FileInfo instead of a FileStream if you do not plan to read the file.


Here's a small benchmark that will provide some numeric values:

private static void Main(string[] args)
{
    string filePath = ...;   // Path to 2.5 GB file here

    Stopwatch z1 = new Stopwatch();
    Stopwatch z2 = new Stopwatch();

    int count = 10000;

    z1.Start();
    for (int i = 0; i < count; i++)
    {
        long length;
        using (Stream stream = new FileStream(filePath, FileMode.Open))
        {
            length = stream.Length;
        }
    }

    z1.Stop();

    z2.Start();
    for (int i = 0; i < count; i++)
    {
        long length = new FileInfo(filePath).Length;
    }

    z2.Stop();

    Console.WriteLine(string.Format("Stream: {0}", z1.ElapsedMilliseconds));
    Console.WriteLine(string.Format("FileInfo: {0}", z2.ElapsedMilliseconds));

    Console.ReadKey();
}

Results:

Stream: 886
FileInfo: 727
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ken2k
  • 48,145
  • 10
  • 116
  • 176
  • 4
    Benchmarking in that way may not be most effective way of testing for a difference (if there is one). I imagine disk caching/os factors will be playing a considerable part in keeping the times down. – PaulG Feb 07 '12 at 16:05
  • 4
    @PaulG You are so right. Benchmarking is **always** more complicated than it looks. The simple benchmark above **only** gives _some indications_ about the actual result. As it doesn't return say 100000 vs 250, I think it's possible to conclude that both methods are _not too much different_ (in terms of computation time). – ken2k Feb 07 '12 at 16:13
40

Both will access the file system metadata rather than reading the whole file. I don't know which is more efficient necessarily, as a rule of thumb I'd say that if you only want to know the length (and other metadata), use FileInfo - whereas if you're opening the file as a stream anyway, use FileStream.Length.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194