2016-08-01 3 views
-4

ByteArrayOutputStreamを使用して1kb〜10GBのサイズのファイルを書き込もうとしていますが、以下の例外がスローされます。私はjdk 6を使用しています。より良い性能のApiをお勧めします。私は同じネットワークボックスを使用して読み書きしています。Byteoutputstreamを使用したJava-Writingの巨大ファイル

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
     at java.util.Arrays.copyOf(Unknown Source) 
     at java.io.ByteArrayOutputStream.grow(Unknown Source) 
     at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source) 
     at java.io.ByteArrayOutputStream.write(Unknown Source) 
     at java.io.OutputStream.write(Unknown Source) 
     at 

コード:

import java.io.BufferedOutputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 


public class PrepareFile { 

    /** 
    * @param args 
    * @throws Exception 
    */ 
    public static void main(String[] args) throws Exception { 
     // TODO Auto-generated method stub 

     new PrepareFile().constructFile("f:\\hello","f:\\output",10000000); 

    } 

    //Writes a large file of 10 GB using input file data of small size by duplicating 
    public void constructFile(String fileName, String outPath, int multiplier) throws Exception { 
     BufferedOutputStream fos = null; 
     FileInputStream fis = null; 

     final File inputFile = new File(fileName); 
     String path = inputFile.getParent(); 
     if (outPath != null && !outPath.isEmpty()) { 
      path = outPath; 
     } 

     fis = new FileInputStream(fileName); 

     try { 



      // read the transactions in the input file. 
      byte[] txnData = new byte[(int) inputFile.length()]; 
      fis.read(txnData); 

      final File outFile = new File(path, "Myfile"); 
      fos = new BufferedOutputStream(new FileOutputStream(outFile)); 
      final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      final ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); 

      //multiplier if input file size is 1 KB and output file is 10 GB, then multiplier value is (1024*1024) 

      for (long i = 1; i <= multiplier; i++) { 

       if(i >=40000 && i % 40000==0){ 
        System.out.println("i value now: "+i); 
        baos.writeTo(fos); 
        baos.reset(); 
        //baos.write(txnData); 
       } 

       // write transactions 
       baos.write(txnData); 
       baos1.write(txnData); //Exception is coming at this line 
      } 

      int Padding = myCustomMethod(baos1.toByteArray()); 

      // write all out data to the output stream 
      baos.writeTo(fos); 

      baos.flush(); 
      baos1.flush(); 
     } catch(Exception e){ 
      e.printStackTrace(); 
     }finally { 
      fos.close(); 
      fis.close(); 
     } 

    } 

    public int myCustomMethod(byte[] b){ 

     //Need complete bytes to prepare the file trailer 
     return 0; 
    } 


} 
+2

*なぜ* ByteArrayOutputStreamに10Gbを書き込んでいますか?あなたが何かをやっている理由を教えていないなら、誰も "より良い"ことを示唆することはできません。 ByteArrayOutputStreamをまったく使用しないでください。なぜなら、メモリではなく意図したターゲットに直接書き込むのはなぜですか? –

+1

十分なメモリがありません。 *ファイルへの書き込み*などの別のテクニックを使用します。 – chrylis

+0

コードを表示してください –

答えて

2

サイズが符号付き32ビットであるようにあなたがByteArrayOutputStream 2 GB以上のバッファを有することができません。

パフォーマンスを向上させたい場合は、ファイルを徐々に処理し、実際に高価なので、大きなメモリコピーを避けてください。

私はライブラリが2GBを超えるバッファをサポートしており、ネイティブメモリを使用し、ヒープの使用を避けるためにファイルにマップしてメインメモリよりも大きくすることができます。

ただし、データを徐々に処理すると、そのような大きなバッファは必要ありません。

は、私もそれが(10年前にリリースされた)は、Java 6あなたのコードに基づいて


EDITよりも優れた64ビット演算を実行としては、Java 8を使用することをお勧め、ByteArrayOutputStreamを使用する必要はありませんファイルを次第に準備することができます。

//Writes a large file of 10 GB using input file data of small size by duplicating 
public void constructFile(String fileName, String outFileName, int multiplier) throws IOException { 
    byte[] bytes; 
    try (FileInputStream fis = new FileInputStream(fileName)) { 
     bytes = new byte[fis.available()]; 
     fis.read(bytes); 
    } 

    try (FileOutputStream fos = new FileOutputStream(outFileName)) { 
     for (int i = 0; i < multiplier; i++) { 
      fos.write(bytes); 
     } 
    } 

    // now process the file "outFileName" 
    // how depends on what you are trying to do. 
    // NOTE: It is entirely possible the file should be processed as it is written. 
} 
+0

私がコピーしたコードスニペットを見て、どのようにクロニクルバイトを使って10 GBファイルですか? – Susanta

+0

私は簡単な例を追加しますが、それはあなたが何をする必要があるかによって異なります。あなたは何が必要な処理を言うことができますか? –

+0

@Susantaは質問のコードに基づいて例を追加しました。 –

関連する問題