DataOutputStream.writeUTF发送含波兰字符内容,客户端readUTF读取乱码问题
问题根因及解决方案
Java/安卓平台的DataOutputStream.writeUTF()与DataInputStream.readUTF()是配套的专属序列化协议,并非通用的UTF-8字符串传输方案,其固定格式为:前2个字节存储后续UTF-8编码内容的字节长度,后面紧跟标准UTF-8编码的字符串内容,仅当收发两端严格按照该协议配对使用时才能正常解析。
你遇到的波兰语特殊字符乱码问题,可按以下优先级排查原因:
- 收发端未配对使用writeUTF/readUTF
如果服务端不是Java语言开发,自行实现writeUTF逻辑时很容易出现两类错误:一是长度计算错误,比如把字符数当成字节数写入前两个字节,导致后续读取错位;二是编码选择错误,未使用标准UTF-8编码字符串,而是用了ISO-8859-1、Windows-1250等单字节编码,波兰语特殊字符在这类编码中的编码值与UTF-8完全不同,就会出现多字节被解析为单个ASCII字符(即你遇到的[)的问题。 - 同Java技术栈但存在多余转码/流操作
如果收发两端均为Java/安卓开发,检查流传输过程中是否存在额外操作:比如服务端调用writeUTF后又手动转码发送了重复内容,或是客户端在调用readUTF之前提前读取了部分流字节,导致偏移量错位,后续全部内容解析错误。
修复方案
- 通用方案(推荐):放弃使用writeUTF/readUTF做跨端字符串传输,改用通用UTF-8传输逻辑:服务端将字符串转为
StandardCharsets.UTF_8格式的字节数组,先发送4字节的字节数组长度(也可使用特殊分隔符区分消息边界),再发送字节内容;客户端读取对应长度的字节数组后,用UTF-8解码为字符串即可,可适配所有技术栈的服务端。 - 同Java栈适配方案:确认服务端为Java技术栈的前提下,保证整个流传输过程没有多余的读写操作,严格配对调用writeUTF和readUTF,不要在两者之间插入其他字节的读写逻辑。
内容的提问来源于stack exchange,提问作者Igorson
相关产品推荐
相关产品推荐

