2012-02-29 17 views
4

ビット単位でファイルを読み取るリーダーを作成しようとしていますが、大きなファイルに問題があります。私は100MBのファイルを読み込もうとしましたが、それは3分以上かかりましたが、うまくいきました。Byte []とjava.lang.OutOfMemoryErrorビット単位でファイルを読み取る

しかし、私は500 MBでファイルを試しましたが、それも開始されませんでした。この行のため:

byte[] fileBits = new byte[len]; 

現在、私は派生を探していて、何も見つかりません。 誰かがそれを解決したことがあり、コード、ヒント、またはアイデアを共有する可能性があります。

if (file.length() > Integer.MAX_VALUE) { 
    throw new IllegalArgumentException("File is too large: " + file.length()); 
} 

int len = (int) file.length(); 
FileInputStream inputStream = new FileInputStream(file); 

try { 
    byte[] fileBits = new byte[len]; 
    for (int pos = 0; pos < len;) { 
     int n = inputStream.read(fileBits, pos, len - pos); 
     if (n < 0) { 
      throw new EOFException(); 
     } 
     pos += n; 
    } 

inputStream.read(fileBits, 0, inputStream.available()); 
inputStream.close(); 
+1

本当にファイル全体が一度に必要ですか?あなたがそれをストリーミングするのを妨げるのは何ですか? –

+2

OutOfMemoryErrorの[検索](https://www.google.com/search?q=OutOfMemoryError)を試しましたか? 'java -mx'を参照してください –

+2

作成する各インデックスは4バイトです。そのうち5億人が2Gのスペースを割り当てようとします。これ以上のメモリやjosh.trowの提案バッファ/ストリーミングなしでは解決できません –

答えて

6

メモリマッピングを試すことをお勧めします。

FileChannel fc = new FileInputStream(file).getChannel(); 
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size()); 

これは、ほとんどすぐに、ファイル全体が利用可能(約10ミリ)を作成していないヒープの隣に使用されます。 BTWファイルは2 GB未満でなければなりません。

1

ファイル全体をメモリに開くべきではありません。固定サイズのバイト配列バッファを作成し、定義したサイズのチャンクからファイルを開く必要があります。

2

ファイル全体を一度にメモリにロードする必要がある場合は、Javaで使用可能なメモリを増やすことをおすすめします。 Xmx(最大ヒープサイズ)またはXms(初期ヒープサイズ)引数を使用してプログラムを呼び出してみてください(必要なメモリ量を事前に知っている場合は後者を使用してください。

java -Xms512m -Xmx1g BigApp 

NIOのMemory-mapped filesを使用することもできます。

関連する問題