应直接使用 Humanizer 库格式化字节数,因其严格按阈值(1024/1000)自动选单位、避免浮点误差、支持二进制/十进制及本地化;若禁用第三方,则须用整数常量逐级比较并仅对大于1的非整数结果保留小数。

直接用 Humanizer 库,别自己写除法逻辑——自己算容易单位错、边界崩、小数位糊,而且 Windows 和 Linux 对“KB”定义还不一样(1000 还是 1024)。
为什么不能直接 bytes / 1024.0 / 1024.0 然后 ToString("F2")
这种硬除会漏掉关键判断:比如 1023 字节该显示 "1023 B",不是 "1.00 KB";999.9 字节四舍五入后也变成 "1.00 KB",但实际还没到 1 KB。更糟的是,double 除法在临界值附近有浮点误差,Math.Round(1023.999, 2) 可能意外进位。单位切换必须基于严格阈值(1024、1024*1024…),且只对非整数单位保留小数位。
用 Humanizer:一行搞定二进制/十进制 + 本地化 + 自动选单位
安装:dotnet add package Humanizer
调用示例:
long bytes = new FileInfo("test.zip").Length;
string display = bytes.Bytes().ToString("0.##", byteFormat: ByteFormat.Binary); // → "2.45 MiB"
string displayDecimal = bytes.Bytes().ToString("0.##", byteFormat: ByteFormat.Decimal); // → "2.57 MB"-
ByteFormat.Binary(默认):按 1024 进制,单位是KiB/MiB,符合 IEC 标准,推荐用于文件系统场景 -
ByteFormat.Decimal:按 1000 进制,单位是KB/MB,适合网络带宽、硬盘厂商标称等场景 - 自动跳过无意义小数:1024 字节 →
"1 KiB",不是"1.00 KiB" - 中文环境会输出
"2.45 米比"(需引用Humanizer.Core.zh包)
真不能引第三方?手写必须守住这三条线
若项目禁用外部依赖,自己实现至少要满足:
- 单位阈值用
const long KB = 1024L、MB = KB * KB等整数常量,别用Math.Pow(1024, 2)(返回double,精度丢) - 逐级比较,不是逐级除:先判
bytes >= TB,再bytes >= GB…避免负值或溢出干扰 - 小数位只在结果 > 1 且 1500 字节 →
1500 / 1024.0 = 1.4648...→"1.46 KB";但1024就直接"1 KB",不补.00 - 务必前置检查
bytes ,防止 <code>UnauthorizedAccessException导致FileInfo.Length返回负值,参与计算会崩
最易被忽略的点:不同平台对“KB”的语义分歧——Windows 资源管理器显示的是二进制(KiB),但某些 API(如 StrFormatByteSize64)返回的字符串单位名是本地化+千分位的,却没暴露进制选择开关;而 .NET 自身没有内置格式化能力,硬写容易在 1023–1025 这个窄区间反复出错。


















