簡體   English   中英

Java Servlet通過HTTP連接提供文件

[英]java servlet serving a file over HTTP connection

我有以下代碼(服務器是Tomcat / Linux)。

//通過當前的HTTP連接發送本地文件

  FileInputStream fin = new FileInputStream(sendFile); int readBlockSize; int totalBytes=0; while ((readBlockSize=fin.available())>0) { byte[] buffer = new byte[readBlockSize]; fin.read(buffer, 0, readBlockSize); outStream.write(buffer, 0, readBlockSize); totalBytes+=readBlockSize; } 

對於某些類型為3gp的文件,當我附加調試器時,請注意以下幾點:

outStream.write(buffer,0,readBlockSize);

它使用以下錯誤中斷一會兒; ApplicationFilterChain.internalDoFilter(ServletRequest,ServletResponse)行:299並且未提供文件。

有什么線索嗎? 謝謝AK

您不能保證InputStream.read(byte [],int,int)會實際讀取所需的字節數:它可能讀取的字節數更少。 即使您對available()的調用也無法提供保證。 您應該使用fin.read的返回值來找出實際讀取了多少字節,然后只將其中的多少寫入輸出。

我想您看到的問題可能與此有關。 如果讀取的塊小於可用大小,則緩沖區將被部分填充,並且當您向輸出寫入太多字節時,這將導致問題。

另外,不要每次循環都分配一個新數組! 這將導致大量不必要的內存分配,這會減慢您的代碼速度,並且可能在available()返回大量內存時導致OutOfMemoryError。

嘗試這個:

int size;
int totalBytes = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((size = fin.read(buffer, 0, BUFFER_SIZE)) != -1) {
    outStream.write(buffer, 0, size);
    totalBytes += size;
}

避免這些類型的問題是我從Commons IO開始的原因。 如果可以的話,您的代碼如下。

FileInputStream fin = new FileInputStream(sendFile);
int totalBytes = IOUtils.copy(fin, outStream);

無需重新發明輪子。

.read()調用返回的字節數可能少於您請求的字節數。 這意味着您需要使用.read() te .read()作為.write()調用的參數:

        int bytesRead = fin.read(buffer, 0, readBlockSize);
        outStream.write(buffer, 0, bytesRead);

除此之外,最好預先分配一個緩沖區並使用它(如果您的文件很大,您可以嘗試使用2Gb緩沖區:-))

byte[] buffer = new byte[4096]; // define a constant for this max length

while ((readBlockSize=fin.available())>0) {                     
    if (4096 < readBlockSize) {
        readBlockSise = 4096;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM