2012-08-14 208 views
3

我有一個1.99 GB的字符文件。現在,我想從該文件中隨機抽取數百萬個子序列,例如從位置90到190,10到110,50000到50100等(每個長度爲100個字符)。Java - Char緩衝區問題

我通常做它用,

FileChannel channel = new RandomAccessFile(file , "r").getChannel(); 
    ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); 
    Charset chars = Charset.forName("ISO-8859-1"); 
    CharBuffer cbuf = chars.decode(buffer); 
    String sub = cbuf.subSequence(0, 100).toString(); 

    System.out.println(sub); 

但是,對於1.99 GB文件,上面的代碼提供了錯誤,

java.lang.IllegalArgumentException 
     at java.nio.CharBuffer.allocate(CharBuffer.java:328) 
     at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:792) 
     at java.nio.charset.Charset.decode(Charset.java:791) 

所以,我用下面的代碼,

FileChannel channel = new RandomAccessFile(file , "r").getChannel(); 
CharBuffer cbuf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()).asCharBuffer() ; 
String sub = cbuf.subSequence(0, 100).toString(); 

System.out.println(sub); 

這不會出現以上錯誤但返回輸出:

ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ä¹ 

這應該是「0111.11億........」

任何人可以幫助我,爲什麼這樣的事情發生,如何解決呢?

+0

基於文檔「IllegalArgumentException - 如果容量是負整數」。可以嘗試通過使用allocate()明確設置容量?http://docs.oracle.com/javase/1.5.0/docs/api/java/nio/CharBuffer.html – kosa 2012-08-14 18:34:40

+0

@thinksteep,我明確地將它設置爲20億,給出IllegalArgumentException異常。 – Arpssss 2012-08-14 18:44:23

+0

爲JVM -Xmx設置分配的內存是多少? – kosa 2012-08-14 18:46:16

回答

2

我只是猜測,但我認爲Charset.decode(ByteBuffer)失敗時,它會嘗試在幕後爲您分配巨大的CharBuffer。同樣,這只是一種預感,但decode方法只能將緩衝區當前位置的字節解碼到極限,因此您可以這樣做。

ByteBuffer buffer = ... 
Charset charset = ... 

buffer.position(0); 
buffer.limit(100); 

System.out.println(charset.decode(buffer)); 

decode方法返回的CharBuffer的容量(以字符)將100

(在一個側面說明,我認爲你的第二次嘗試給出錯誤的輸出,因爲你沒有使用特定字符集來解碼您的CharBuffer。)