考虑一个通用的字节阅读器,实现以下简单的API,从一个无法访问的数据结构中读取未指定数量的字节:
public interface ByteReader
{
public byte[] read() throws IOException; // Returns null only at EOF
}
如何将上述内容有效地转换为标准Java InputStream,以便使用InputStream
类定义的所有方法的应用程序按预期工作?
一个简单的解决方案是将InputStream
子类化为
read()
ByteReader
方法,根据需要调用read(...)
InputStream
方法
InputStream read()
方法时,一次返回1个字节。然而,这需要更多工作才能有效(例如,为了避免多字节阵列分配)。此外,对于扩展到大输入大小的应用程序,将所有内容读入内存然后处理不是一种选择。
可以使用的任何想法或开源实现?
答案 0 :(得分:1)
我认为,通过使用“转换”,替换是可以接受的。
最简单的方法是使用ByteArrayInputStream
,它已经提供了您正在寻找的所有功能(但必须包装现有数组),或者使用已经提供的任何其他功能{{3}}。 1}}用于从各种来源读取数据。
看起来你可能冒着重新发明轮子的风险。如果可能,我会考虑完全取消您的InputStream
界面,而是选择其中一个选项:
ByteReader
。ByteInputStream
类(取决于数据来源)。InputStream
。我到处都坚持现有的InputStream
课程。我不知道你的代码是如何构造的,但是你可以,例如,为你当前的数据源添加一个InputStream
方法,并让它们返回一个适当的已存在getInputStream()
(或者自定义子类,如果必要)。
顺便提一下,我建议在您自己的IO类中避免使用术语InputStream
,因为{SDK}已经在Java SDK中大量使用Reader
来指示对编码字符数据进行操作的流读取器(相反)通常对原始字节数据进行操作的Reader
。
答案 1 :(得分:1)
围绕返回的数组创建多个ByteArrayInputStream
实例,并在提供连接的流中使用它们。例如,您可以使用SequenceInputStream
。
欺骗是要实现可以使用Enumeration<ByteArrayInputStream>
类的ByteReader
。
编辑:我已经实现了这个答案,但最好是创建自己的InputStream
实例。不幸的是,这个解决方案不允许您优雅地处理IOException
。
final Enumeration<ByteArrayInputStream> basEnum = new Enumeration<ByteArrayInputStream>() {
ByteArrayInputStream baos;
boolean ended;
@Override
public boolean hasMoreElements() {
if (ended) {
return false;
}
if (baos == null) {
getNextBA();
if (ended) {
return false;
}
}
return true;
}
@Override
public ByteArrayInputStream nextElement() {
if (ended) {
throw new NoSuchElementException();
}
if (baos.available() != 0) {
return baos;
}
getNextBA();
return baos;
}
private void getNextBA() {
byte[] next;
try {
next = byteReader.read();
} catch (IOException e) {
throw new IllegalStateException("Issues reading byte arrays");
}
if (next == null) {
ended = true;
return;
}
this.baos = new ByteArrayInputStream(next);
}
};
SequenceInputStream sis = new SequenceInputStream(basEnum);