我正在清理工作中的一些代码库,其中一个较旧的类用于读写数据。此数据是US-ASCII编码字符串和二进制编码基元的混合。
当前实现使用DataInputStream,但正如您在文档中所看到的,由于与将字节转换为字符相关的问题,不推荐使用readLine()
方法。虽然这个编码问题并没有真正为我们提供,但是弃用是一个问题,因为它已经无法在某些版本的OpenJDK 7上运行,并且弃用意味着它可以在将来完全删除。 “官方”替代方法是使用BufferedReader中的readLine
,但我们无法与DataInputStream完全交换,因为BufferedReader无法真正处理二进制编码的基元。
“混合”这两个类的问题是当BufferedReader缓冲流时,它会使流标记前进。这意味着后续对DataInputStream中的readDouble()
方法的调用将因IOExceptions或EOFExceptions而失败,因为流标记的实际位置不是“应该”在应用程序逻辑的上下文中。
我查看了某种hacky mark()
/ reset()
策略,但有时该流由FileInputStream支持,后者不支持mark()
/ reset()
。
除了改变我们的数据协议以将原语写为字符或编写我自己的readLine()
实现(这是非常重要的)之外,有没有办法实现这一目标?我现在甚至愿意考虑使用外部库。
答案 0 :(得分:4)
如果当前代码库运行良好且您唯一的问题是deprecation
标记,我个人建议您复制readLine
类的DataInputStream
方法中的代码并移动它到帮助者/实用程序类。 readLine
的{{1}}方法不使用大量的实例变量,所以通过一些工作,你应该可以正常使用它。示例调用将如下所示:DataInputStream
。这将确保即使删除该方法,您的代码库也不会受到影响。
是的,它是hacky,是的,它看起来有点难看但是最快,可能是最安全的替代方案(对剩余代码库的最小改动)。
答案 1 :(得分:1)
我认为你应该创建一个DataInputStream
的自定义子类,它添加一个readLine
- 类似于你需要它的方法。 (您甚至可以覆盖现有的readLine()
方法。)
是的,有效的实现并非易事,但如果您将自定义类堆叠在BufferedInputStream
之上,则可能会使用简单的实现。
答案 2 :(得分:0)
我遇到了类似的问题,我设法使用缓冲区大小为1的BufferedReader
解决了这个问题。
因此,BufferedReader.readLine()方法是无缓冲的。
InputStreamReader inr=(new InputStreamReader( mInputStream(),"ASCII"));
BufferedReader mReader=new BufferedReader(inr,1);