2013-03-21 33 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()調用。