发布于2026-07-15 阅读(0)
扫一扫,手机访问
你可能遇到过这样的情况:用 DataInputStream 的 readUTF 方法读取字符串时,突然抛出一个 ja va.io.UTFDataFormatException: encoded string too long 的错误。这不是什么奇怪的 bug,而是 readUTF 本身的一道“硬门槛”——它要求字符串的 UTF-8 编码字节长度不能超过 65535(也就是 216−1)。
这个限制的根源在于 readUTF 的工作方式。它先读 2 个字节,这两个字节是一个无符号短整型,用来表示后续 UTF 编码字节的长度。2 个字节能表示的最大值就是 65535,超出这个范围,协议层面就不认了。
这里有个很容易被忽略的点:字符串的字符数和它的 UTF-8 编码字节数,完全是两码事。一个字符串可能只有几万个字符,但里面只要混入中文、emoji 或其他 Unicode 字符,编码后的体积就可能迅速膨胀(一个汉字就要占 3 个字节)。而这个限制跟 JVM 或 JDK 版本无关,是 DataInputStream 规范中雷打不动的强制要求。
别只盯着 String.length() 看,那个数字是字符数,对判断这个限制没什么帮助。真正要查的是 UTF-8 编码后的字节数:
string.getBytes(StandardCharsets.UTF_8).length 拿到真实的字节长度当需要传输长文本时,最直接的办法就是放弃 readUTF,改用更灵活的组合方式。比如:
dos.writeInt(len)),再写原始字节(dos.write(bytes))new String(din.readNBytes(len), StandardCharsets.UTF_8) 还原字符串BufferedReader/BufferedWriter 加行协议,也可以考虑 ObjectOutputStream(但要留意序列化开销和兼容性问题)有意思的是,这个限制虽然不复杂,但踩坑的人确实不少。以下几个场景尤其容易中招:
说到底,这个问题不复杂,但确实容易忽略。关键在于区分“字符数”和“UTF-8 字节数”,并且在设计阶段就把传输协议的边界明确下来。

售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8