
お世話になります。
ブラウザ画面からファイルをアップロードし、そのバイナリデータを返すメソッドを作成したのですが、約50MB以上のファイルを使用するとOutOfMemoryエラーとなりJava heap spaceが足りないといわれてしまいます。ヒープサイズをあげればエラーはしなくなるとはおもいますが、根本的な解決にはならないと思います。
public byte[] upload(FormFile ff) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = ff.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
byte[] byteData;
try {
int data = 0;
byte[] buffer = new byte[1024];
while ((data = bis.read(buffer) != -1) {
baos.write(buffer, 0, data);
}
byteData = baos.toByteArray();
} catch (IOException e) {
throw e;
} finally {
if (null != bis) {
bis.close();
}
}
return byteData;
}
以上のようなメソッドなのですが、おかしい点はありますでしょうか。
指摘していただけると助かります。
よろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
iBatisは、BLOBに対してデフォルトではbyte配列で対応するので、
ちょっと大きいデータを扱うと、この問題が発生するんですよね。
BLOBとStreamをマッピングする、カスタムTypeHandlerを作成して対応します。
iBatis側で用意されていないのは、DBによってBLOBの扱いが違うから。
No.1
- 回答日時:
50MBのファイルなら50MB全部を読み出してからbaos.toByteArray()を実行していますよね。
どうしてもファイル全体を読み込み終えてからでないと処理できないような内容ならば、ファイル全体を保持してもOutOfMemoryにならないだけの大きさのヒープを確保するしかありません。upload()がreturnした配列はその後どのように使われるのですか? ファイルを最後まで読み出してから一気に処理するのではなく、少しずつ読み出しては処理する(処理し終えた部分はメモリ上から消す)のを繰り返すという形には変更できませんか? そのように書き換えられる種類の処理であればそれが根本的な解決策です。
そういう書き換えができない場合に少しでも限界を遠ざけるにはどうしたらいいか、ですが、ファイルの長さは読み出し前には分からないでしょうか? ByteArrayOutputStreamに一度溜め込んでからtoByteArray()で変換するのはメモリの無駄です。ByteArrayOutputStreamを使うのをやめて、ファイルの長さ分のbyte配列をnewで初めから確保し、bis.read()でそのbyte配列に直接読み込むようにすれば大幅な節約になるはずです。それでも、ファイル全体をメモリ上に読み込もうとする限り200MBのファイルを扱おうとしたらOutOfMemoryになるかもしれません。
回答ありがとうございます。
取得したbyte配列はエンティティに格納してDBに格納しようとしています。
バイナリデータをDBに格納するのが必要なためByteArrayOutputStreamを使っていました。
InputStreamをそのまま格納できれば一番早いのかと思ったのですがiBatisでそれができるのかわからなかったからです。
>ByteArrayOutputStreamを使うのをやめて、ファイルの長さ分のbyte配列をnewで初めから確保し、bis.read()でそのbyte配列に直接読み込むようにすれば大幅な節約になるはずです。
これをちょっと試してみようと思います。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DXFファイルをVBで取り込み、図...
-
バイナリファイルでOutOfMemory...
-
VB6.0 MSFlexGridのMouseRowプ...
-
ファイル入力のデータを構造体...
-
エクセルのプロパティーでセキ...
-
エクセルvbaでdocuworksprinter...
-
frxファイルの役目
-
Wordで差込印刷した後に別々の...
-
[エクセル]コピーするとオブジ...
-
ハイフネーションされている英...
-
xcopyでのバッチコピー方法でコ...
-
デスクトップの画像をhtmlに表...
-
ThisWorkbookがあるフォルダ更...
-
【VBA】ExcelマクロでCSVファイ...
-
Windows10でコマンドプロンプト...
-
ファイルサーバ上のファイルが...
-
エクセルのハイパーリンクがコ...
-
ファイルを複数選択した時のフ...
-
カンマ区切りのCSVファイルから...
-
エクセルで複数のコメントのサ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ファイル内の(&H0A)を(&H0D0A)...
-
バイナリファイルでOutOfMemory...
-
Cで2次元配列にCSVファイルを...
-
ファイルから構造体へデータを...
-
ファイル入力のデータを構造体...
-
RGBのバイナリデータをCImageに...
-
Mscomm を使用してバイナリでデ...
-
カウント数について
-
VB6.0 MSFlexGridのMouseRowプ...
-
テキストファイルを後ろから読...
-
DXFファイルをVBで取り込み、図...
-
C言語の問題です。
-
VBScriptの配列は、要素数を指...
-
VBAでテキストファイルの改行を...
-
ファイルからビット単位での読...
-
Unicodeのファイル読み込みがう...
-
バイナリ出力
-
インデックスが配列の境界外で...
-
配列操作について
-
CSVファイルによる検索の高速化
おすすめ情報