news 2026/8/27 15:00:21

快速看懂 ByteSize 源码:一个 long Bits 如何优雅驱动十进制与二进制双体系转换

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
快速看懂 ByteSize 源码:一个 long Bits 如何优雅驱动十进制与二进制双体系转换

快速看懂 ByteSize 源码:一个 long Bits 如何优雅驱动十进制与二进制双体系转换

【免费下载链接】ByteSizeByteSize is a utility class that makes byte size representation in code easier by removing ambiguity of the value being represented. ByteSize is to bytes what System.TimeSpan is to time.项目地址: https://gitcode.com/gh_mirrors/byt/ByteSize

ByteSize 是一款 C# 字节大小工具库,它让字节单位转换变得清晰无歧义——就像System.TimeSpan之于时间。它的核心设计只有一个思路:用一个long Bits字段存储真实值,其余所有单位(KB、MB、KiB、GiB……)全部按需换算而来。今天带你完整剖析这套十进制/二进制双体系转换的源码实现,几行关键代码就能看懂。

先搞清楚:为什么需要 KB 和 KiB 两套体系

很多新手第一次会困惑:同样是"1 KB",硬盘厂商说是 1000 字节,而 Windows 任务管理器里的内存又按 1024 算。这不是谁错了,而是两套标准并存:

体系换算比例缩写典型场景
📊 十进制(SI 标准)1 KB =1000 BKBMBGBTB硬盘容量、云存储计费
🔢 二进制(IEC 标准)1 KiB =1024 BKiBMiBGiBTiB内存、内存分配器

ByteSize 从 v2.0 起同时支持这两套体系(见 CHANGELOG.md 中的破坏性变更记录),这也是理解它源码的起点。

单一数据源:Bits 就是"宇宙真理"

打开核心文件src/ByteSizeLib/ByteSize.cs,结构体ByteSize只有两个字段:

public long Bits { get; } // 唯一整数真值 public double Bytes { get; } // Bits / 8,只是缓存

构造函数里的逻辑简单到极致(ByteSize.cs):

public ByteSize(long bits) { Bits = bits; Bytes = (double)bits / BitsInByte; // BitsInByte = 8 }

为什么选long而不是double因为位(bit)是不可再分的最小单位,整数存储零精度损失;而加减乘除的结果若出现小数字节,Bytesdouble承接,兼顾精度与灵活性。所有比较、相等、排序操作最终都落在Bits上,比如CompareTo只有一行:this.Bits.CompareTo(other.Bits)

十进制换算:5 个常量撑起整个体系

src/ByteSizeLib/DecimalByteSize.cs是一个partial 结构体,只干一件事——定义十进制换算:

  • 5 个比例常量:BytesInKiloByte = 1_000一直到BytesInPetaByte = 1_000_000_000_000_000
  • 5 个符号常量:KBMBGBTBPB
  • 5 个只读属性:KiloBytes => Bytes / BytesInKiloByte
  • 5 个工厂方法:FromKiloBytesFromMegaBytes……全部收敛为new ByteSize(value * 常量)

也就是说,"1.5 MB" 并不神秘——它只是1500000 字节的另一种叫法,落到 Bits 就是 12000000。

二进制换算:同样 5 件套,只是底数换了

src/ByteSizeLib/BinaryByteSize.cs结构与十进制文件完全对称,只是常量换成了 1024 的幂:

常量
BytesInKibiByte1_024
BytesInMebiByte1_048_576
BytesInGibiByte1_073_741_824
BytesInTebiByte1_099_511_627_776
BytesInPebiByte1_125_899_906_842_624

两个文件合起来,ByteSize就拥有了bits、bytes + 十进制 5 级 + 二进制 5 级共 12 个视角,但它们读写的始终是同一个Bits。这正是"一个 long 驱动双体系"的全部秘密:没有转换,只有除法

自动挑最大整数单位:ToString 的精髓

用户最在意的输出体验在ToString里(ByteSize.cs)。它配合LargestWholeNumberDecimalSymbol这类属性,从上往下逐级探测,找到"值 ≥ 1 的最大单位":

var size = ByteSize.FromKiloBytes(1000); size.ToString(); // "1 MB" ——十进制视角 size.ToBinaryString(); // "0.98 MiB" ——二进制视角

细节也很讲究:

  • 值为 0 时固定输出"0 B",避免出现诡异的"0 b"
  • 格式化串里写KBMiB等符号即可强制指定体系;
  • 数字格式走标准的double.ToString,默认0.##保留两位小数,且支持区域性(de-DE文化下的1,55 kib也能正确解析)。

字符串解析:把 "1.55 MB" 读回来

Parse方法(ByteSize.cs)采用"数字与单位切半"策略:先找到第一个非数字字符,把前半段double.TryParse成数值,后半段按 switch 分派:

  • b/B大小写敏感——位不允许小数("1.5 b"会抛FormatException);
  • KBMB走十进制工厂方法;KiBMiB走二进制工厂方法;
  • 解析失败可用TryParse静默兜底,风格与 .NET 基类一致。

此外还有一个隐藏彩蛋:ByteSize标注了[TypeConverter(typeof(ByteSizeTypeConverter))]src/ByteSizeLib/ByteSizeTypeConverter.cs),意味着设计器、配置文件里可以直接写字符串,框架自动完成 Parse/ToString。

工程组织:测试如何保障双体系正确性

源码只有 6 个 .cs 文件,测试却按体系分得清清楚楚:

  • src/ByteSizeLib.Tests/Decimal/—— 十进制方向的算术、构造、解析、字符串测试
  • src/ByteSizeLib.Tests/Binary/—— 二进制方向的同名四件套
  • 顶层src/ByteSizeLib.Tests/—— 跨体系的公共行为

构建也很轻:dotnet build编译、dotnet test跑测试(见根目录 Makefile)。多目标框架定义在src/ByteSizeLib/ByteSizeLib.csproj,通过 netstandard 同时覆盖 .NET Core、.NET Framework 与 UWP。

新手避坑指南 ⚠️

  1. 别把 KB 和 KiB 混用FromKiloBytes(1024)是 1_024_000 字节,而FromKibiBytes(1024)是 1_048_576 字节,二者相差 2.4%。
  2. 升级 v1 老代码要小心:v1 中KB = 1024 B,v2 起KB = 1000 B,需要 1024 语义时请改用FromKibiBytes
  3. ++/--自增自减以字节为单位,且源码 TODO 注释暗示作者自己也在考虑移除它。
  4. 乘法/除法返回的仍是 ByteSizeFromBytes(4) * FromBytes(2)得到 8 字节,语义上"字节乘字节"并不常见,使用时想清楚即可。

总结:这套设计的可复用之处

  • 单一数据源:所有单位都是同一个long的投影,永远不会出现"KB 属性与 Bytes 属性互相打架";
  • partial struct 分文件:十进制与二进制各占一文件,互不干扰,阅读路径清晰;
  • 常量即文档:比例与符号全部public const,既可供外部复用,又自带说明;
  • 输出交给 LargestWholeNumber 系列属性:UI 展示一行代码搞定,还顺带支持本地化。

如果你正在写任何涉及容量、带宽、存储配额的 C# 程序,这套"一个长整型 + 双向换算表"的模式,几乎可以直接抄进自己的领域模型里。

【免费下载链接】ByteSizeByteSize is a utility class that makes byte size representation in code easier by removing ambiguity of the value being represented. ByteSize is to bytes what System.TimeSpan is to time.项目地址: https://gitcode.com/gh_mirrors/byt/ByteSize

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/27 14:47:04

【小白教程】一文讲清楚大模型中8个关键词及原理:LLM、Transformer、GPT、Bert、预训练、微调、深度学习、Token

什么是大模型? 你是不是脑子里浮现的是 OpenAI、ChatGPT、DeepSeek?还有各式各样能跳个舞、可以翻个跟头的机器人?再深入点的,还能说出训练与推理。 有没有一种感觉:就是身边的信息都在声嘶力竭的鼓吹大模型正在改变世…

作者头像 李华
网站建设 2026/8/27 14:42:45

电动车识别检测数据集:1306张图片+VOC/YOLO/JSON三格式,附YOLO实战教程

简介:目标检测任务中,数据的质量和格式往往决定模型的上限。无论是训练YOLO、Faster R-CNN还是MMDetection,都离不开规范化的标注文件。常见的数据集格式包括VOC的XML、YOLO的TXT以及COCO风格的JSON,它们各自服务于不同的工具链&a…

作者头像 李华
网站建设 2026/8/27 14:42:10

从零开始学大模型:LLMs、RAG与AI Agent的区别与应用,程序员必看收藏

前言对于接触 AI 相关的朋友,平时都会遇到很多新的概念,先不说什么大模型的技术性的术语,就AI应用方面的术语就非常多。 而且,现在还是依旧层出不穷。 在技术迭代到一定程度之后,它就必然会满足更多的实际场景&#xf…

作者头像 李华