C#获取文件大小 C#如何得到文件的字节大小

来源:这里教程网 时间:2026-02-21 17:41:25 作者:

FileInfo.Length
获取文件字节大小最直接

只要文件存在且有读取权限,

FileInfo
是最稳妥的方式。它返回
long
类型,能正确处理大于 2GB 的文件(
int
会溢出)。

常见错误是直接用

File.OpenRead(path).Length
,但没做异常捕获和资源释放,容易卡住句柄或抛出
UnauthorizedAccessException

必须先检查
File.Exists(path)
,否则
FileInfo
构造时不会报错,但访问
.Length
会抛
FileNotFoundException
路径含中文、空格、特殊符号时没问题,.NET 自动处理编码 不要用
new FileInfo(path).Length
在循环里反复创建对象——
FileInfo
内部会查文件系统,有开销
string path = @"C:\data\report.pdf";
if (File.Exists(path))
{
    var info = new FileInfo(path);
    long bytes = info.Length; // ✅ 正确获取字节数
}

File.GetAttributes
+
GetFileSizeEx
是 Windows 原生方案

当需要绕过 .NET 封装、或在极低层操作(如驱动交互、性能敏感场景),可调用 Windows API

GetFileSizeEx
。它比
FileInfo
略快,但仅限 Windows,且需手动 P/Invoke。

注意:这个 API 不检查文件是否存在,传入无效路径会返回

false
,且
lpFileSize
值未定义——必须检查返回值,不能只看输出参数。

GetFileSizeEx
返回的是
bool
,成功才可信;失败时
out long
是垃圾值
需要
[DllImport("kernel32.dll")]
,且
SafeHandle
IntPtr
打开的句柄必须保持有效直到调用完成
普通业务代码完全没必要用这个,
FileInfo.Length
已足够可靠

避免用
FileStream.Length
做常规获取

虽然

FileStream
也有
.Length
属性,但它要求流已打开、且底层句柄支持获取大小(比如网络流、内存流就不行),还容易引发
ObjectDisposedException

典型误用:

using var fs = File.OpenRead(path); var len = fs.Length;
—— 这段代码本身没错,但多了一次打开/关闭开销,且如果文件正被其他进程写入,可能读到不一致的长度(尤其 NTFS 上未刷新的缓存)。

FileStream.Length
本质是调用
GetFileSizeEx
,但多了托管层封装和安全检查
若已有一个打开的
FileStream
(比如你正在读它),那用
.Length
是合理的;否则纯为取大小,就绕远了
别用
fs.Position = 0; fs.Read(...)
再算长度——这是严重误用,效率极低且不可靠

大文件或网络路径要注意权限与延迟

当路径指向远程 SMB 共享、OneDrive 同步文件夹、或 NTFS 加密文件时,

FileInfo.Length
可能触发实际 I/O 或权限校验,导致阻塞数秒甚至超时。

这不是 .NET 的 bug,而是底层文件系统行为。例如访问一个 OneDrive “按需文件”,首次调用

.Length
可能触发下载。

try/catch
捕获
IOException
UnauthorizedAccessException
TimeoutException
考虑异步包装(虽然
FileInfo
本身无异步 API),用
Task.Run(() => new FileInfo(path).Length)
避免 UI 线程卡死
对不确定路径,先用
File.GetAttributes(path)
快速判断是否存在和是否为目录,再决定是否取大小
真正容易被忽略的点:不是所有“文件”都返回真实大小——比如某些虚拟文件系统(WIM、ISO 挂载点)、符号链接目标不可达、或 NTFS 稀疏文件,
FileInfo.Length
返回的是逻辑大小,不是磁盘占用。需要磁盘占用得用
GetCompressedSize
GetDiskFreeSpaceEx
等额外 API。

相关推荐