Encoding.UTF8.GetByteCount() 是计算字符串 UTF-8 字节长度最稳妥的方法,它准确反映网络传输和存储所需字节数,避免乱码、截断及跨平台差异。
用 Encoding.UTF8.GetByteCount() 算字节长度最稳妥
字符串的“字节长度”不是字符串长度,它取决于编码方式。c# 中 string 默认是 utf-16,但存文件、发 http、进数据库时往往要转成 utf-8 字节流——这时候就得用对应编码去算。
别直接用 str.Length,那是字符数(char count),一个中文字符占 2 个 char,但在 UTF-8 里占 3 个字节;英文字符在 UTF-16 占 2 字节,在 UTF-8 只占 1 字节。
-
Encoding.UTF8.GetByteCount(str)是最常用、最安全的选择,兼容性好,符合现代 API 和网络协议默认要求 - 如果对接老系统(比如某些 Windows API 或遗留 DB),可能得用
Encoding.Default(通常是 GB2312/GBK),但务必确认清楚目标环境,否则中文会乱码或截断 - 别用
Encoding.Unicode.GetByteCount()(即 UTF-16),它返回的是str.Length * 2,看似简单,但几乎没人真按这个存或传
中英文混排时,Encoding.GetByteCount() 自动处理,不用手动分段
有人担心“中英文混合要不要分开算”,其实完全不必。所有 Encoding 类的 GetByteCount() 方法内部已按 Unicode 码点查表,自动决定每个字符占几个字节:ASCII 字符(U+0000–U+007F)在 UTF-8 下统一占 1 字节,中文(如 U+4F60)占 3 字节,emoji(如 U+1F600)占 4 字节。
- 示例:
Encoding.UTF8.GetByteCount("a你好")返回5(1 + 3 + 1) - 错误做法:先用
char.IsLetterOrDigit()分中英文再分别乘系数——既慢又错,漏掉标点、全角空格、日文假名等 - 注意:BOM(byte order mark)不参与计算,
GetByteCount()只算内容本身,不加 BOM
Encoding.GetBytes().Length 和 GetByteCount() 性能差一倍以上
想获取字节长度时,别写 Encoding.UTF8.GetBytes(str).Length。它会真实分配字节数组、拷贝全部内容,纯属浪费内存和 CPU。
-
GetByteCount()是纯计算,无内存分配,快且轻量 -
GetBytes()适合你接下来真要拿字节数组干活(比如写入Stream),否则就是画蛇添足 - 在高频日志、序列化、HTTP header 构建等场景,这个差异会被放大,尤其字符串较长或调用频繁时
小心 Encoding.Default 在不同机器上返回不同结果
Windows 上 Encoding.Default 通常是系统 ANSI 代码页(如简体中文 Win10 是 GBK),但 Linux/macOS 的 .NET Core/.NET 5+ 里它固定为 UTF-8。同一段代码,在开发机(Win)和 Docker(Linux)里算出的字节长度可能完全不同。
- 除非明确对接旧 Win32 API 或必须兼容某款老硬件协议,否则一律避免
Encoding.Default - 跨平台项目务必显式指定
Encoding.UTF8,并在文档或配置里写死,别依赖环境 - 如果必须用 GBK,用
Encoding.GetEncoding(936)显式声明,比Default更可读、更可控
真正容易被忽略的是:字节长度影响的不只是存储大小,还常是协议边界(比如 MQTT payload limit)、数据库字段 VARBINARY 容量、甚至加密块大小。算错一个字节,可能让整条请求被静默截断。











