2016-04-01 5 views
3

私は独自の個人用HTTPサーバーをJavaからゼロから作成しました。 これまではうまくいっていますが、大きな欠陥が1つあります。 大きなファイルをブラウザに渡そうとすると、Javaヒープスペースエラーが発生します。私はJVMを介してこのエラーを修正する方法を知っていますが、私はこれのための長期的な解決策を探しています。JAVA:すべてのファイルをブラウザに正しくストリームします。

//declare an integer for the byte length of the file 
int length = (int) f.length(); 

//start the fileinput stream. 
FileInputStream fis = new FileInputStream(f); 

//byte array with the length of the file 
byte[] bytes = new byte[length]; 

//write the file until the bytes is empty. 

while ((length = fis.read(bytes)) != -1){ 
    write(bytes, 0, length); 
} 
flush(); 

//close the file input stream 
fis.close(); 

この方法では、が正常に完全にそれをストリームが、私は、ファイルの長さのバイト配列を作成していますので、問題は、あるブラウザにファイルを送信します。ファイルが非常に大きくなると、ヒープスペースエラーが発生します。

私はを持っています。この問題は以下のようにバッファを使用することで解消されました。ヒープスペースエラーはもう発生しません。 BUT以下に示す方法では、ブラウザのファイルが正しくストリームされません。これは、ファイルバイトがシャッフルされ、ブラウザに一緒に送信されているかのようです。

final int bufferSize = 4096; 
byte buffer[] = new byte[bufferSize]; 

FileInputStream  fis = new FileInputStream(f); 
BufferedInputStream bis = new BufferedInputStream(fis); 

    while (true) 
    { 
    int length = bis.read(buffer, 0, bufferSize); 
    if (length < 0) break; 
    write(buffer, 0, length); 
    } 
flush(); 
bis.close(); 
fis.close(); 

注1:

すべて正しいレスポンスヘッダがブラウザに完全に送信されています。

注2:

どちらの方法が完全にコンピュータブラウザ上を仕事だけ最初の方法は、スマートフォンのブラウザ上で動作します(時にはそれは私にヒープ領域のエラーを与えます)。 誰かがブラウザにファイルを正しく送信して正しくストリームする方法を知っていれば、私は非常に幸せな人になるでしょう。

ありがとうございます!私はそれを見ることができるように:)

+3

あなたは 'Content-Length'ヘッダーを送信しているようには見えず、' Content-Type'も表示されません。ヘッダーはHTTPにとってかなり重要です。 –

+0

ああ、私はそれを私の質問に追加するのを忘れてしまった。応答ヘッダーが正しく送信されています。 –

+0

Apacheコモンズを使用していますか?もしそうなら、 'IOUtils.copy(inputStream、outputStream);'を試すことができます。 – nickb

答えて

2

あなたが許可することができBufferedInputStreamからの読み取りそのバッファリングを処理するために、バッファ、何の理由にはありませんすべてをbyte[]に読み込みます(もちろん、ファイル全体のうちbyte[]はありません)。一度にbyteを読み、ストリームの内部バッファに頼ります。何かのように、

FileInputStream fis = new FileInputStream(f); 
BufferedInputStream bis = new BufferedInputStream(fis); 
int abyte; 
while ((abyte = bis.read()) != -1){ 
    write(abyte); 
} 
+0

これは実際にそれが働くElliott、非常にありがとう:) –

0

EMMは...、とにかくあなたのコード内でチャンクを使用しようと、 は私もApacheのHttpClient+FileUploadソリューションは< = 2.1ギガバイトか何か(約ファイルサイズの制限があり、覚えることができるよう私が間違っている場合、私はまだ解決策を試してみましたが、上の[ファイルと組み合わせてjava.io.RandomAccessFileを使用することができますテスト(入力/出力)ストリームとしてしていない...ので、それは少し難しいものです

を私を修正クライアントとサーバーは一度にファイル全体を読み書きしないようにしますが、厄介なアウトメモリエラーを避けるために、例えば< = 30MBブロックと言うことができます。 RandomAccessFileを使用した例はここにあります。https://examples.javacodegeeks.com/core-java/io/randomaccessfile/java-randomaccessfile-example/

しかし、あなたはまだ細かいことを言いません:(あなたのクライアントは一般的なJavaアプリケーションであると思われますか?あなたには、いくつかの追加情報をお持ちの場合は


私に知らせてください

幸運:)

関連する問題