二进制文件读写异常:素数ArrayList存储后最后行读取错误排查
可能的问题原因及排查步骤
1. 换行符\n的字节偏移问题
- 写入时用
\n(ASCII 0x0A)分隔行,但读取时对换行符的处理容易出错:- 要是写入时直接写了1字节的
\n,但读取时跳过换行符的逻辑错了(比如多跳了字节,或者最后一行写完没加\n,读取时还硬要跳),会导致最后一行开头的8字节计数读错——可能读了部分换行符加素数字节,后续所有素数解析全乱。 - 查下读取代码:读完前两行素数后,是不是准确跳过了1字节的
\n?最后一行写完后有没有加\n?读取最后一行时有没有多余的跳过操作?
- 要是写入时直接写了1字节的
2. 3字节素数的读写逻辑不匹配
- 写入端:确认
getByteSize判定为3字节的素数,写入时真的只写了3字节?别不小心用了writeInt()写了4字节,那读取时按3字节解析肯定错。 - 读取端:读取3字节素数的字节顺序得和写入一致。比如写入时是先写高位字节、再中间、最后低位,读取时就得按
(read() << 16) | (read() << 8) | read()来拼,要是顺序搞反(先读低位),解析出的数完全不对。
3. 最后一行的计数与实际写入数量不符
- 虽然
countNumbersInEachLine算出是760888,但得确认写入时真的写了这么多3字节素数:- 算下文件总字节数对不对:
8(第一行计数)+54*1+1(\n)+8(第二行计数)+6488*2+1(\n)+8(第三行计数)+760888*3,和实际文件大小比。要是文件比预期小,说明写入最后一行时可能提前终止(比如抛了异常没捕获);要是大了,可能多写了无关字节。 - 检查写入最后一行的循环:是不是遍历了所有3字节素数,没漏也没重复。
- 算下文件总字节数对不对:
4. 文件流未刷新就关闭
- 写完最后一行后,有没有先调用
outputStream.flush()再关流?要是没刷新,缓冲区里的最后一批数据可能没写到文件里,读取时最后一行素数就会不完整。
5. 读取时未处理EOF边界
- 读取最后一行素数时,循环次数是按读取到的计数(760888)来的,但要是读取过程中
read()返回了-1(到文件末尾了),还继续拼接字节,就会解析出错误的数值。得在读取每个字节时判断是否到了EOF。
内容的提问来源于stack exchange,提问作者BlakieSl
相关产品推荐
相关产品推荐

