将Java字节读取器转换为InputStream
考虑一个通用的字节读取器实现以下简单API,以从无法访问的数据结构中读取未指定数量的字节:将Java字节读取器转换为InputStream,java,byte,bytearray,inputstream,Java,Byte,Bytearray,Inputstream,考虑一个通用的字节读取器实现以下简单API,以从无法访问的数据结构中读取未指定数量的字节: public interface ByteReader { public byte[] read() throws IOException; // Returns null only at EOF } 如何将上述内容有效地转换为标准,以便使用InputStream类定义的所有方法的应用程序按预期工作 一个简单的解决方案是将InputStream子类化为 根据InputStream的read(…)
public interface ByteReader
{
public byte[] read() throws IOException; // Returns null only at EOF
}
如何将上述内容有效地转换为标准,以便使用InputStream
类定义的所有方法的应用程序按预期工作
一个简单的解决方案是将InputStream
子类化为
InputStream的read(…)
方法的需要,调用ByteReader的read()
方法
InputStream read()
方法时,每次返回一个字节InputStream
从各种源读取数据
看来你可能正在冒着在这里重新发明轮子的风险。如果可能的话,我会考虑完全删除您的<代码> ByteReader < /C>接口,而使用以下选项之一:
ByteInputStream
InputStream
类(取决于数据源)InputStream
InputStream
类。我不知道您的代码是如何构造的,但是您可以,例如,向您当前的数据源添加一个getInputStream()
方法,并让它们返回一个适当的已经存在的InputStream
(或自定义子类,如果需要)
顺便说一句,我建议在您自己的IO类中避免使用术语
Reader
,因为Reader
已经在Java SDK中大量使用,以指示对编码字符数据进行操作的流读取器(与通常对原始字节数据进行操作的InputStream
相反).围绕返回的数组创建多个ByteArrayInputStream
实例,并在提供连接的流中使用它们。例如,你可以用这个
诀窍是实现一个枚举
,它可以使用ByTerReader
类
编辑:我已经实现了这个答案,但是最好还是创建自己的InputStream
实例。不幸的是,此解决方案不允许您优雅地处理IOException
final Enumeration basEnum=新枚举(){
Bytearrayinputs;
布尔结束;
@凌驾
公共布尔值hasMoreElements(){
若果(完){
返回false;
}
if(baos==null){
getNextBA();
若果(完){
返回false;
}
}
返回true;
}
@凌驾
public ByteArrayInputStream nextElement(){
若果(完){
抛出新的NoTouchElementException();
}
如果(baos.available()!=0){
返回宝;
}
getNextBA();
返回宝;
}
私有void getNextBA(){
字节[]下一个;
试一试{
next=byteReader.read();
}捕获(IOE异常){
抛出新的IllegalStateException(“读取字节数组的问题”);
}
if(next==null){
结束=真;
返回;
}
this.baos=新的ByteArrayInputStream(下一个);
}
};
SequenceInputStream sis=新SequenceInputStream(basEnum);
检查了源代码。我认为它使用了类似的想法,也许你可以扩展它,从你的数据结构中读取是的,我在写问题之前已经检查过了。本质上需要一个类似fill()的函数,但在ByteArrayInputStream实现中它似乎太复杂了,所以我想知道是否有更简单的方法。@PNS您可以使用Arrays.fill()
在ByteInputStream的基础数组上。这仅适用于将一个值设置为多个数组位置。:-)不,你不能,但那不是问题的主题。在检查效率之前,必须先将ByterReader转换为InputStream。我知道SequenceInputStream,但使用ByteArrayInputStream既不高效,也不同步。仅当检索和缓冲的字节不足以满足InputStream read(…)方法的要求时,才需要调用ByteReader read()方法。new BufferedInputStream(new ByteArrayInputStream(…)
不够吗?不,请参阅我对答案的评论。感谢和+1的实现,但这是没有效率的。想象一下,在一个大文件上必须调用ByteReader.read()数千次或数百万次……什么意思,效率不高?您为我们提供了一个我使用的单一接口。它不会创建任何额外的缓冲区。它唯一创建的是附加对象,这些对象很小,可以很容易地进行垃圾收集。您向我们寻求帮助,但您认为您有足够的知识立即判断任何提交。您的字节数据最初来自哪里?new BufferedInputStream(new ByteArrayInputStream(…)
不够吗?在我的用例中没有原始数据访问,因此描述了ByteReader接口。了解dat的位置会很有帮助
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);