1

ファイルをバイト配列に変換する必要がありますが、.movファイル(1.32 Gb)では変換できません。この方法は、小さな.txtファイルとJPEG画像では正常に機能しますが、MOVファイルで実行しようとするとできません。NullPointerExceptionが発生します。

コード:

public byte[] fileToByteArray(File file){
    ByteArrayOutputStream baos = null;
    InputStream fis = null;
    try{
        byte[] buffer = new byte[(int)file.length()];
        baos = new ByteArrayOutputStream();
        fis = new FileInputStream(file);
        int read;
        while((read = fis.read(buffer)) != -1){
            baos.write(buffer, 0, read);
        }
    }catch(Exception ex){
        System.out.println("Error: 1");
    }finally{
        try{
            if(baos != null){
                baos.close();
            }
        }catch(Exception ex){
            System.out.println("Error: 2");
        }
        try{
            if(fis != null){
                fis.close();
            }
        }catch(Exception ex){
            System.out.println("Error: 3");
        }
        return baos.toByteArray();
    }
}
4

3 に答える 3

1

この行で:

return baos.toByteArray();

この行が例外をスローした場合でもnullのままであっても、無条件に間接参照しています...baos

byte[] buffer = new byte[(int)file.length()];

例外をスローしたのではないかと思います(推測では、メモリ不足です)...しかし、「すべての例外をキャッチし、印刷して無視する」という例外処理戦略により、すべきでないときに続行します。 。

これに対する当面の修正は、本当にキャッチしたい例外のみをキャッチすることです。これは、ほぼ確実にIOException、この場合にのみ発生するはずです。catch実際、私はおそらく、あなたが書いたコードでは、おそらくコード以外では、句をまったく使用しないでしょうclose。(他の場所で例外を隠すために例外が発生することは望ましくありませんclose。Java7を使用している場合は、try-with-resourcesステートメントを使用して、これらすべてを簡単に開始できるようにしてください。)

あなたがしている方法で例外を「処理する」ことは非常に悪い考えです-あなたは基本的に何がうまくいかなくても続行したいと言っています、そしてそれはあなたが運が良ければ、あるいはあなたが運が良ければあるエラーを別のエラーに導くだけです運が悪いと、気付かないうちに、良いデータを悪いデータで上書きするなど、悪い状態の変更を行うことになります。

さて、より大きな問題については、巨大な配列を割り当てようとしているのですが、JVMにそれほど多くのメモリを使用するように指示していないのではないかと思います。次のようなものから始める必要があります。

java -Xmx3G ...

...それだけのメモリを使用できる64ビットJVMを使用していると仮定します。

于 2012-09-09T08:12:49.650 に答える
0

1.32GBは約2^30.4バイトです。このOutOfMemoryError行でおそらく投げられるでしょう:

byte[] buffer = new byte[(int)file.length()];

その結果、コードフローは例外ハンドラーにジャンプします(印刷を試みますが"Error: 1"、この場合は機能する場合と機能しない場合あります)。その結果、コードフローがfinallyブロックに到達したとき、baosはまだnull、したがって、NullPointerExceptionです。

私がアドバイスしたい解決策は、1.32GBのファイルをメモリに読み込もうとしないことです...少なくともそのように。

于 2012-09-09T08:12:37.873 に答える
0

なぜあなたはそれを例えば4K/8K / 16Kバイト配列のチャンクで読んでいないのですか?そうすれば、メモリが不足することはありません。この方法で、20GBもの巨大なファイルをネットワーク経由でコピーしました。

于 2012-09-09T08:31:51.777 に答える