[英]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.