2013-03-21 148 views
2

我需要以二进制文件形式提供数据作为十六进制字符串。当前的实现将整个文件加载到内存中,将其转换为十六进制字符串并将十六进制字符串作为字节数组提供给另一个组件。将FileInputStream转换成一个返回十六进制的流

我现在面临的问题是,这个文件有时非常大,所以我得到“OutOfMemoryException”。该组件还接受InputStream作为输入,所以我想我会将我的FileInputStream封装到另一个以十六进制字符串形式返回文件的流中。

然而,我不知道如何做到这一点,虽然InputStream的子类看起来很简单,但我可以看到这是非常容易出错的读取方法和特殊情况。如果这个车轮已经存在,我也不会重新发明它。

对此提出建议?

+1

为什么你首先将* text *数据(一个十六进制*字符串*)作为字节数组传递?你可以逐块传递数据吗?基本上我们需要在这里了解更多关于“其他组件”的信息· – 2013-03-21 11:16:52

+0

我将数据传递给一个Web服务器,该服务器希望在发布请求中将二进制数据格式化为十六进制。我目前正在使用ByteArrayEntity:http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/entity/ByteArrayEntity.html,但我希望使用InputStreamEntity代替。 – monoceres 2013-03-21 11:19:51

+0

但是,我可以通过十六进制字符串作为一个StringEntity来代替,但这不是我的代码.. :) – monoceres 2013-03-21 11:25:50

回答

2

这是我们创建一个InputStream

InputStream is = new BufferedInputStream(new HexInputStream(new FileInputStream("1.test"))); 

,并把它传递给该组件的基本思想

class HexInputStream extends FilterInputStream { 

    HexInputStream(InputStream in) { 
     super(in); 
    } 

    @Override 
    public int read(byte[] buff, int off, int len) throws IOException { 
     int b = super.read(); 
     String hex = String.format("%02x", b); 
     buff[0 + off] = (byte)hex.charAt(0); 
     buff[1 + off] = (byte)hex.charAt(1); 
     return 2; 
    } 
} 

。在is.read上,我们总是读取1个字节并将其转换为2个十六进制字符。

需要一些努力才能使这个想法真正起作用。

+0

谢谢,我会采用这种方法。 – monoceres 2013-03-21 13:05:18

0

Apache Commons IO提供了一个针对您的问题的实用程序,它也尝试覆盖复杂的IO方案。这里的链接

hexdump from apache commons

希望这有助于

+0

十六进制似乎希望输入作为字节数组。由于我的文件很大,我无法在内存中保存整个文件。 – monoceres 2013-03-21 11:24:15

1

你应该通过扩展FilterInputStream(或FilterReader),并覆盖相关的读取方法和别人,你打算实现这一点。例如,read()方法需要读取一个字节,将其转换为两个十六进制字节,返回第一个字节,并保留第二个字节用于下一个read()调用。