不使用System.IO.FileInfo获取文件大小?

ser*_*ave 13 c# filesize fileinfo filepath

是否可以在不使用C#的情况下获取文件的大小System.IO.FileInfo

我知道你可以分别使用Path.GetFileName(yourFilePath)和得到其他东西,比如Name和Extension Path.GetExtension(yourFilePath),但显然不是文件大小?有没有其他方法我可以获得文件大小而不使用System.IO.FileInfo

唯一的原因是,如果我是正确的,FileInfo会抓取比我真正需要的更多的信息,因此如果我需要的唯一东西是文件的大小,那么收集所有这些FileInfo需要更长的时间.有更快的方法吗?

Pet*_*ete 8

我使用这两种方法执行了基准测试:

    public static uint GetFileSizeA(string filename)
    {
        WIN32_FIND_DATA findData;
        FindFirstFile(filename, out findData);
        return findData.nFileSizeLow;
    }

    public static uint GetFileSizeB(string filename)
    {
        IntPtr handle = CreateFile(
            filename,
            FileAccess.Read,
            FileShare.Read,
            IntPtr.Zero,
            FileMode.Open,
            FileAttributes.ReadOnly,
            IntPtr.Zero);
        long fileSize;
        GetFileSizeEx(handle, out fileSize);
        CloseHandle(handle);
        return (uint) fileSize;
    }
Run Code Online (Sandbox Code Playgroud)

针对2300多个文件运行,GetFileSizeA需要62-63ms才能运行.GetFileSizeB花了18秒.

除非有人看到我做错的事情,否则我认为答案很清楚哪种方法更快.

有没有办法可以避免实际打开文件?

更新

将FileAttributes.ReadOnly更改为FileAttributes.Normal减少了时间,以便两种方法的性能相同.

此外,如果你跳过CloseHandle()调用,GetFileSizeEx方法会快20-30%,但我不知道我会推荐它.


Alo*_*Bar 5

从我做过的简短测试中,我发现使用FileStream平均比使用Pete的GetFileSizeB慢1毫秒(在网络共享上花了我大约21毫秒......).就我个人而言,我个人更喜欢保持在BCL限制范围内.

代码很简单:

using (var file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    return file.Length;
}
Run Code Online (Sandbox Code Playgroud)


d--*_*--b 0

你可以试试这个:

[DllImport("kernel32.dll")]
static extern bool GetFileSizeEx(IntPtr hFile, out long lpFileSize);
Run Code Online (Sandbox Code Playgroud)

但这并没有太大的进步...

以下是来自 pinvoke.net 的示例代码:

IntPtr handle = CreateFile(
    PathString, 
    GENERIC_READ, 
    FILE_SHARE_READ, 
    0, 
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_READONLY, 
    0); //PInvoked too

if (handle.ToInt32() == -1) 
{
    return; 
}

long fileSize;
bool result = GetFileSizeEx(handle, out fileSize);
if (!result) 
{
    return;
}
Run Code Online (Sandbox Code Playgroud)

  • 这与“FileStream.Length”相同,只是可读性较差的版本。 (3认同)