完整指南:单位换算、格式化与速率计算)
开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载导读ByteSizeExtensions是 Humanizer 中面向字节量ByteSize的一组静态扩展方法解决了 .NET 开发中两个高频痛点把裸露的数值转换为带单位的ByteSize值如1024.Bytes()以及把ByteSize输出为2 GB、10.5 KB这类人类可读的字符串。本指南以 Humanizer 3.0.1 官方 API 文档 Humanizer.ByteSizeExtensions.md 为骨架结合仓库源码与测试完整讲解每一个扩展方法的签名、语义、底层换算原理以及如何用Per方法计算传输速率。读完本文你将能直接在自己的 .NET 项目中用这些方法完成文件大小展示、日志格式化与网速统计等场景。一、类概览ByteSizeExtensions 是什么ByteSizeExtensions是定义在Humanizer命名空间下的一个静态类官方文档对其定位只有一句话Provides extension methods for ByteSize为ByteSize提供扩展方法。它继承自System.Object声明如下public static class ByteSizeExtensions在仓库源码 ByteSizeExtensions.cs 中可以看到该类的实现方式是每个扩展方法都是对ByteSize静态工厂方法的薄封装——例如Kilobytes(this int input)内部直接返回ByteSize.FromKilobytes(input)。这意味着扩展方法本身不承载换算逻辑真正的单位换算与数值存储全部集中在ByteSize结构体内部扩展方法只是提供了一套流畅的、链式友好的调用语法。使用这些扩展方法不需要额外配置只要引入Humanizer命名空间即可using Humanizer; // 直接把数值当作某单位得到 ByteSize 实例 ByteSize size 10.Kilobytes();二、单位换算扩展方法把数值当作某单位文档核心部分是 6 组单位扩展方法Bits、Bytes、Kilobytes、Megabytes、Gigabytes、Terabytes。它们语义统一Considers input as bits / bytes / kilobytes / ...把输入当作比特 / 字节 / 千字节……并返回ByteSize。2.1 方法签名与重载矩阵每组单位方法都针对多种数值类型提供了重载覆盖 .NET 全部常见整数类型与double。以文档完整列出的签名为准方法族如下单位方法支持的输入类型this参数内部实现Bits(...)byte、sbyte、short、ushort、int、uint、longByteSize.FromBits(input)Bytes(...)byte、sbyte、short、ushort、int、uint、long、doubleByteSize.FromBytes(input)Kilobytes(...)byte、sbyte、short、ushort、int、uint、long、doubleByteSize.FromKilobytes(input)Megabytes(...)同上 8 种类型ByteSize.FromMegabytes(input)Gigabytes(...)同上 8 种类型ByteSize.FromGigabytes(input)Terabytes(...)同上 8 种类型ByteSize.FromTerabytes(input)签名示例文档中的原始声明public static Humanizer.ByteSize Bits(this byte input); public static Humanizer.ByteSize Bytes(this double input); public static Humanizer.ByteSize Kilobytes(this long input); public static Humanizer.ByteSize Megabytes(this uint input); public static Humanizer.ByteSize Gigabytes(this short input); public static Humanizer.ByteSize Terabytes(this sbyte input);值得注意Bits不提供double重载而Bytes到Terabytes均提供double重载。从源码看这是因为ByteSize内部以位为原子单位存储见下文 2.3Bits面向整数值设计而字节级单位天然需要支持小数如 1.5 KB。2.2 从源码结构看当前版本还包含更多单位3.0.1 API 文档只收录了上述 6 组方法但当前仓库源码 ByteSizeExtensions.cs 中同一模式还扩展到了更大的单位与 IEC 二进制单位Petabytes、Exabytes、Pebibytes均提供byte到long及double重载分别对应ByteSize.FromPetabytes、ByteSize.FromExabytes、ByteSize.FromPebibytes。从源码结构看可以推断这些是文档版本之后陆续加入的 API用法与旧单位完全一致ByteSize huge 2.Exabytes(); // 2 * 10^18 字节 ByteSize iec 5.Pebibytes(); // 5 * 2^50 字节2.3 底层换算原理ByteSize 的存储模型要正确使用这些扩展方法必须理解ByteSize的内部存储。在 ByteSize.cs 中ByteSize是一个结构体核心状态只有两个double byteSize字节数和long Bits位数向上取整得到public struct ByteSize(double byteSize) { public long Bits { get; } (long)Math.Ceiling(byteSize * BitsInByte); public double Bytes { get; } byteSize; // ... }换算常量ByteSize.cspublic const long BitsInByte 8; public const long BytesInKilobyte 1024; // 即 1 KiB public const long BytesInMegabyte 1048576; // 即 1 MiB public const long BytesInGigabyte 1073741824; // 即 1 GiB public const long BytesInTerabyte 1099511627776; // 即 1 TiB public const long BytesInPetabyte 1000000000000000; // 10^15十进制 public const long BytesInExabyte 1000000000000000000; // 10^18十进制由这些常量可以得出几个关键事实KB/MB/GB/TB 采用 1024 进制即与 KiB/MiB/GiB/TiB 数值等价源码中BytesInKibibyte等常量直接复用旧值而PB/EB 采用 1000 进制——这正是ByteSizeUnitSystem.Legacy所描述的混合单位行为见第四节。各FromXxx工厂方法只是乘法FromKilobytes(value)即new(value * BytesInKilobyte)。测试 CreatingTests.cs 验证了换算结果例如ByteSize.FromKilobytes(1.5)得到1536字节ByteSize.FromGigabytes(1.5)得到1610612736字节。Bits属性对byteSize * 8做Math.Ceiling向上取整源码注释 Get ceiling because bits are whole units因此ByteSize.FromBytes(1.5)的Bits为 12测试 CreatingTests.cs 验证。2.4 单元测试验证创建类测试 CreatingTests.cs 对ByteSize的工厂方法与单位换算做了完整的断言验证例如构造new ByteSize(1099511627776)1 TB后其Kilobytes、Megabytes、Gigabytes、Terabytes属性分别为 1073741824、1048576、1024、1直观印证了 1024 进制换算链。这些测试同样适用于通过扩展方法创建的ByteSize实例因为两者最终都收敛到相同的工厂方法。三、Humanize 方法把 ByteSize 变成2 GBHumanize是ByteSizeExtensions中最重要的格式化方法文档对它的描述是Turns a byte quantity into human readable form, eg 2 GB把字节量转换为人类可读形式如 2 GB。3.1 三个重载的完整签名文档完整列出了三个重载// 重载 1只指定格式字符串format 可空默认 null public static string Humanize(this Humanizer.ByteSize input, string? format null); // 重载 2指定格式字符串 格式提供器 public static string Humanize(this Humanizer.ByteSize input, string? format, System.IFormatProvider? formatProvider); // 重载 3只指定格式提供器 public static string Humanize(this Humanizer.ByteSize input, System.IFormatProvider formatProvider);参数说明参数类型含义inputByteSize要格式化的字节量formatstring?使用的字符串格式如0.00、KB、#.## GB为null或空白时使用ByteSize默认格式formatProviderIFormatProvider?数字格式化提供器如特定CultureInfo影响数字的小数点、千位分隔符等源码实现ByteSizeExtensions.cs非常直白本质是把参数转发给ByteSize.ToStringpublic static string Humanize(this ByteSize input, string? format null) string.IsNullOrWhiteSpace(format) ? input.ToString() : input.ToString(format); public static string Humanize(this ByteSize input, IFormatProvider formatProvider) input.ToString(formatProvider); public static string Humanize(this ByteSize input, string? format, IFormatProvider? formatProvider) string.IsNullOrWhiteSpace(format) ? input.ToString(formatProvider) : input.ToString(format, formatProvider);3.2 默认行为自动选择最大的整数单位不带format调用Humanize()或ToString()时ByteSize会自动选取最大的、数值绝对值不小于 1 的单位来展示。这一点在 ByteSize.cs 的GetLargestWholeNumberSymbol/LargestWholeNumberValue中实现从 EB 开始逐级向下检查直到Math.Abs(该单位值) 1。测试 ToStringTests.cs 给出了明确的行为证据// 默认格式输出 Assert.Equal(10.5 KB, ByteSize.FromKilobytes(10.5).ToString()); // 自动降级到 KB512 KB 而非 0.5 MB Assert.Equal(512 KB, ByteSize.FromMegabytes(.5).ToString(#.#)); // 负值同样自动选单位 Assert.Equal(-512 KB, ByteSize.FromMegabytes(-.5).ToString(#.#));3.3 自定义 format 字符串的规则format参数既可以是纯数字格式也可以包含单位 token。由 ByteSize.cs 的ToString(string?, IFormatProvider?)实现可知format为null或G时统一替换为0.##最多保留两位小数。format 中不含#或0时会被当作纯单位 token自动拼接为0.## format。例如Humanize(KB)等价于0.## KB测试ReturnsDefaultNumberFormat验证10.5.Kilobytes().Humanize(KB)输出10.5 KB。format 中含单位 token 时按 token 匹配对应单位并输出该单位下的数值。KB、MB、GB、TB、PB、EB及KiB、MiB、GiB、TiB、PiB的匹配不区分大小写但bbit与Bbyte严格区分大小写源码注释明确 Byte and Bit symbol look must be case-sensitive。#.##会被规范化替换为0.##保证自定义格式下小数位行为一致。测试验证ToStringTests.cs// 自定义数字精度 Assert.Equal(10.1234 KB, ByteSize.FromKilobytes(10.1234).ToString(#.#### KB)); // 指定单位输出 Assert.Equal(10 b, ByteSize.FromBits(10).ToString(##.#### b)); Assert.Equal(10 B, ByteSize.FromBytes(10).ToString(##.#### B)); Assert.Equal(10 MB, ByteSize.FromMegabytes(10).ToString(##.#### MB)); Assert.Equal(10 TB, ByteSize.FromTerabytes(10).ToString(##.#### TB)); // 指定精度的固定格式 Assert.Equal(10.0 TB, ByteSize.FromTerabytes(10).ToString(0.0 TB));3.4 语言与区域设置formatProviderformatProvider控制数字本身的格式化如小数点是.还是,同时参与单位词的本地化。从源码看当传入CultureInfo时数字格式会经过LocaleNumberFormattingOverrides.GetFormattingNumberFormat的覆盖处理单位符号则由Configurator.GetFormatter(culture)解析的 Formatter 提供ByteSize.cs。这意味着Humanize输出的数字与单位都具备区域感知能力适合直接用于多语言 UI。四、Per 方法从字节量到传输速率Per是文档收录的最后一个扩展方法用于把某段时间内的字节量转换为可操作的速率对象public static Humanizer.ByteRate Per(this Humanizer.ByteSize size, System.TimeSpan interval);参数语义文档原文参数含义sizeQuantity of bytes字节数量intervalInterval to create rate for创建速率所依据的时间间隔源码实现ByteSizeExtensions.cs只是构造了一个ByteRatepublic static ByteRate Per(this ByteSize size, TimeSpan interval) new(size, interval);4.1 ByteRate 与 HumanizeByteRateByteRate.cs持有Size与Interval两个属性并提供Humanize方法计算速率。默认按每秒输出也支持TimeUnit.Minute、TimeUnit.Hour但注意只支持这三者其余时间单位会抛出NotSupportedException测试ThrowsOnUnsupportedData验证public string Humanize(TimeUnit timeUnit TimeUnit.Second) Humanize(null, timeUnit); public string Humanize(string? format, TimeUnit timeUnit TimeUnit.Second, CultureInfo? culture null) { var displayInterval timeUnit switch { TimeUnit.Second TimeSpan.FromSeconds(1), TimeUnit.Minute TimeSpan.FromMinutes(1), TimeUnit.Hour TimeSpan.FromHours(1), _ throw new NotSupportedException(timeUnit must be Second, Minute, or Hour), }; return new ByteSize(Size.Bytes / Interval.TotalSeconds * displayInterval.TotalSeconds) .Humanize(format, culture) / timeUnit.ToSymbol(culture); }典型用法与测试期望ByteRateTests.cs// 400 字节 / 1 秒 → 400 B/s ByteSize.FromBytes(400).Per(TimeSpan.FromSeconds(1)).Humanize(); // 4 MB 数据用了 2 秒 → 4 MB/s ByteSize.FromBytes(4 * 1024 * 1024).Per(TimeSpan.FromSeconds(2)).Humanize(); // 15 MB 数据用了 60 秒 → 15 MB/s ByteSize.FromBytes(15 * 60 * 1024 * 1024).Per(TimeSpan.FromSeconds(60)).Humanize();按分钟/小时展示的示例TimeUnitTests// 1 MB 在 60 秒内传完按分钟展示 → 1 MB/min ByteSize.FromMegabytes(1).Per(TimeSpan.FromSeconds(60)).Humanize(TimeUnit.Minute); // 按小时展示 → 1 MB/h ByteSize.FromMegabytes(1).Per(TimeSpan.FromSeconds(3600)).Humanize(TimeUnit.Hour);ByteRate.ToString()直接委托给Humanize()默认每秒速率因此ByteSize.FromBytes(400).Per(TimeSpan.FromSeconds(1)).ToString()输出400 B/s。4.2 速率对象还支持比较与相等判断从 ByteRate.cs 可以看到ByteRate实现了IComparableByteRate与IEquatableByteRate比较和相等判断都基于归一化后的每秒字节数BytesPerSecondSize.Bytes / Interval.TotalSeconds。测试验证400 B/10s 与 800 B/20s 归一化后相等CompareTo返回 0不同速率的比较结果符合预期。这让ByteRate可以直接放入SortedSet、用于排序或去重。五、进阶显式单位系统与复合格式当前源码新增 API3.0.1 文档之外当前仓库源码还提供了两组与Humanize同族的高阶扩展属于同一主题的自然延伸一并说明5.1 HumanizeWithUnitSystem显式选择单位体系ByteSizeUnitSystemByteSizeUnitSystem.cs定义了三种单位体系枚举值含义Legacy 0Humanizer 传统混合单位KB~TB 用 1024 进制PB/EB 用 1000 进制DecimalSi 1十进制 SI 单位相邻单位之间为 1000 倍BinaryIec 2二进制 IEC 单位相邻单位之间为 1024 倍KiB/MiB/GiB...对应的扩展方法HumanizeWithUnitSystem(this ByteSize, ByteSizeUnitSystem, string? format null, IFormatProvider? formatProvider null)ByteSizeExtensions.cs当传入Legacy时退化为普通Humanize否则调用ByteSize.Format按显式单位体系格式化若unitSystem未定义则抛ArgumentOutOfRangeExceptionformat 非法则抛FormatException。5.2 HumanizeComposite / HumanizeCompositeWithUnitSystem复合格式输出这两个方法ByteSizeExtensions.cs把字节量拆成多个降序单位输出例如10 KB 2 Bpublic static string HumanizeComposite( this ByteSize input, int precision 2, IFormatProvider? formatProvider null, string separator , bool toWords false)precision最多返回的非零部分数量必须 ≥ 1否则抛ArgumentOutOfRangeExceptionseparator各部分之间的分隔符默认空格不允许nulltoWords为true时使用本地化单位单词如 kilobyte而非符号如 KB内部从 EB 逐级向下拆分剩余的不足 1 字节的位以Bit收尾。HumanizeCompositeWithUnitSystem则叠加了DecimalSi/BinaryIec显式单位体系选择内部维护DecimalCompositeUnits与BinaryCompositeUnits两组单位表分别以 kB/MB/GB/TB/EB 和 KiB/MiB/GiB/TiB/PiB 递降。相关行为由 ByteSizeUnitSystemTests.cs 与 ByteSizeMultiSectionFormatTests.cs 覆盖验证。六、实战示例组合使用把扩展方法与Per串联可以实现典型的文件大小 传输速率场景using Humanizer; // 1) 展示文件大小自动选单位 long fileBytes 13_107_200; Console.WriteLine(fileBytes.Bytes().Humanize()); // 12.5 MB // 2) 强制单位与精度 Console.WriteLine(fileBytes.Bytes().Humanize(#.## MB)); // 12.5 MB // 3) 指定区域格式数字使用逗号小数点的区域 var de CultureInfo.GetCultureInfo(de-DE); Console.WriteLine(fileBytes.Bytes().Humanize(de)); // 数字按 de-DE 规则输出 // 4) 下载速率500 MB 用了 32 秒 var size 500.Megabytes(); var interval TimeSpan.FromSeconds(32); Console.WriteLine(size.Per(interval).Humanize()); // 15.6 MB/s Console.WriteLine(size.Per(interval).Humanize(TimeUnit.Minute)); // 按分钟换算七、小结ByteSizeExtensions是 Humanizer 字节能力的前端入口其设计呈现清晰的层次构造层Bits/Bytes/Kilobytes/Megabytes/Gigabytes/Terabytes及源码中扩展的Petabytes/Exabytes/Pebibytes把裸数值包装成带单位的ByteSize格式化层Humanize系列方法自动选取最大的整数单位输出并支持自定义数字格式、单位 token 与区域提供器速率层PerByteRate把字节量 时间间隔变为可比较、可排序、可本地化的传输速率进阶层HumanizeWithUnitSystem与HumanizeComposite(WithUnitSystem)提供显式单位体系与复合格式的精细控制。所有行为均有源码与测试佐证单位换算逻辑见 ByteSize.cs扩展方法实现见 ByteSizeExtensions.cs速率对象见 ByteRate.cs行为断言见 CreatingTests.cs、ToStringTests.cs 与 ByteRateTests.cs。在你的项目里引入 Humanizer 包后这些扩展方法即可直接使用无需任何初始化配置。赞分享开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载相关推荐Humanizer ByteSizeExtensions 完全指南.NET 字节与位单位转换、人性化格式化与速率计算的扩展方法全景Humanizer ByteSizeExtensions 完全指南.NET 字节与位单位转换、人性化格式化与速率计算的扩展方法全景 本篇技术指南围绕 Huma开发工具Humanizer ByteSizeExtensions 扩展方法完全指南字节单位构建、人类可读格式化与传输速率计算Humanizer ByteSizeExtensions 扩展方法完全指南字节单位构建、人类可读格式化与传输速率计算 Humanizer 的 ByteSize开发工具Humanizer ByteSizeExtensions 扩展方法全解析位、字节与传输速率的人性化展示Humanizer ByteSizeExtensions 扩展方法全解析位、字节与传输速率的人性化展示 Humanizer 是 .NET 生态中专注于字符串、开发工具上一篇1.8.2 - 2020-10-22下一篇AutoDock Vina批量对接教程如何高效处理大规模配体库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考