C#读取文件长度的最快方法

31

我正在使用 fs.Length,其中 fs 是一个 FileStream

这是一个 O(1) 操作吗?我认为这只是读取文件的属性,而不是通过文件查找到达末尾的位置。我需要查找长度的文件大小范围可能从 1 MB 到 4-5 GB。

然而,我注意到还有一个 FileInfo 类,它也有一个 Length 属性。

这两个 Length 属性理论上需要相同的时间吗?或者因为必须先打开 FileStream,所以 fs.Length 更慢?

2个回答

43

.NET中获取文件大小的自然方式是你提到的FileInfo.Length属性。

我不确定Stream.Length是否更慢(它不会读取整个文件),但如果你不打算读取文件,使用FileInfo而不是FileStream肯定更自然。


这是一个小型基准测试,将提供一些数字值:

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();
}

结果:

Stream: 886
FileInfo: 727

4
以此方式进行基准测试可能不是检测差异(如果有的话)最有效的方法。我想磁盘缓存/操作系统因素在保持时间短的方面会发挥相当大的作用。 - PaulG
4
@PaulG 你说得太对了。基准测试总是比看起来更复杂。上面的简单基准测试仅仅提供了一些实际结果的指示。因为它没有返回例如 100000 对比 250,我认为可以得出两种方法在计算时间上没有太大差异的结论。请注意,“not too much different”表示“没有太大差异”,并非完全相同。 - ken2k

40

两者都会访问文件系统元数据而不是读取整个文件。我不确定哪个更有效,但作为一个经验法则,如果你只想知道长度(和其他元数据),可以使用FileInfo - 而如果你无论如何都要打开文件流,请使用FileStream.Length


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接