【发布时间】:2016-04-01 16:02:24
【问题描述】:
所以我从头开始用 Java 创建了我自己的个人 HTTP 服务器。 到目前为止,它运行良好,但存在一个主要缺陷。 当我尝试将 大文件 传递给浏览器时,我收到 Java 堆空间错误。我知道如何通过 JVM 修复此错误,但我正在寻找长期解决方案。
//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();
这种方式将文件发送到浏览器成功并完美流式传输但问题是,因为我正在创建一个具有文件长度的字节数组。当文件很大时,我得到堆空间错误。
我已通过使用如下所示的缓冲区消除此问题,并且不再出现堆空间错误。 但是下面显示的方式不能正确地在浏览器中流式传输文件。就好像文件字节被打乱并一起被发送到浏览器。
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:
两种方式在计算机浏览器上完美工作,但只有第一种方式在上工作智能手机的浏览器(但有时它会给我堆空间错误)。 如果有人知道如何正确地将文件发送到浏览器并正确流式传输它们,我将是一个非常非常高兴的人。
提前感谢您! :)
【问题讨论】:
-
您似乎没有发送
Content-Length标头,我也没有看到Content-Type。标头对 HTTP 相当重要。 -
哦,我忘了把它添加到我的问题中。响应标头已正确发送!
-
我可以对您的代码风格和一些细节提出质疑,但是从浏览器的角度来看,第二个版本的行为应该与第一个相同。更具体地说明您的意思,“就好像文件字节正在被打乱并一起发送到浏览器。”这对故障排除没有帮助。
-
您使用什么
write()方法来写入数据?也许这个错误就在那里,并且只有在重复调用时才会出现。 -
您不应该将整个文件读入缓冲区以进行流式传输,通过缓冲您应该一次读取和写入一个字节(并让缓冲区处理它)。