使用Java BufferedReader读取SRT文件出现垃圾字节值问题咨询
SRT文件读取异常字节的成因分析
问题场景
你尝试用Java的BufferedReader逐行读取SRT文件,文件内容如下:
2 00:00:40,665 --> 00:00:44,806 <i>♪ Nants ingonyama ♪</i>
使用的代码片段:
public void parseSubtitles(@NonNull final MultipartFile subtitleFile) { InputStream is = subtitleFile.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } }
调试时发现异常:
- 第一行“2”对应的字节数组为
[-3, -1, -3, -1, 50, 0, 0, 0] - 下一行字节数组仅为
[0](对应空行) - 字幕时间行的字节数组为
[0, 48, 0, 48, 0, 58, 0, 48, 0, 48, 0, 58, 0, 52, 0, 48, 0, 44, 0, 54, 0, 54, 0, 53, 0, 32, 0, 45, 0, 45, 0, 62, 0, 32, 0, 48, 0, 48, 0, 58, 0, 48, 0, 48, 0, 58, 0, 52, 0, 52, 0, 44, 0, 56, 0, 48, 0, 54, 0]
其他SRT文件无此问题,下面是成因分析:
核心成因
编码不匹配
这个异常的SRT文件采用的是UTF-16BE编码,而你代码中的InputStreamReader使用了系统默认编码(通常是UTF-8或GBK)读取,两者不匹配导致解析混乱。- 时间行的字节数组里,每个ASCII字符对应两个字节(高字节为0,低字节是字符的ASCII值),比如'0'对应
0,48,':'对应0,58,这完全符合UTF-16BE的编码规则(每个字符占2字节,大端序存储)。 - 正常SRT文件一般用UTF-8编码,所以读取时不会有问题。
- 时间行的字节数组里,每个ASCII字符对应两个字节(高字节为0,低字节是字符的ASCII值),比如'0'对应
损坏的字节顺序标记(BOM)
文件开头的[-3,-1,-3,-1]是损坏的BOM:- 标准UTF-16BE的BOM是
FE FF(对应字节值-2, -1),而这里的字节不符合规范,进一步干扰了编码解析逻辑,导致第一行的'2'被错误解析(实际'2'的UTF-16BE编码应该是0,50,但文件里是50,0,0,0,疑似混入了UTF-32的字节格式)。
- 标准UTF-16BE的BOM是
空行的来源
下一行的[0]字节,用UTF-8解析时会被识别为无效的空字符,进而被readLine()当成空行返回。
解决思路
读取时指定正确的编码格式,比如明确使用UTF-16BE:
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_16BE));
如果不确定文件编码,可以先通过检测文件开头的BOM字节或尝试多种常见编码来适配。
内容的提问来源于stack exchange,提问作者Suvid Sahay
相关产品推荐
相关产品推荐

