JAVA:正确地将任何文件流式传输到浏览器

JAVA:正确地将任何文件流式传输到浏览器,java,file,stream,server,Java,File,Stream,Server,因此,我从头开始用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 = n

因此,我从头开始用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();
final int bufferSize=4096;
字节缓冲区[]=新字节[bufferSize];
FileInputStream fis=新的FileInputStream(f);
BufferedInputStream bis=新的BufferedInputStream(fis);
while(true)
{
int length=bis.read(缓冲区,0,缓冲区大小);
如果(长度<0)断裂;
写入(缓冲区,0,长度);
}
冲洗();
二、关闭();
fis.close();
注1:

所有正确的响应标题正完美地发送到浏览器

注2:

这两种方法都能在计算机浏览器上完美运行,但只有第一种方法能在智能手机的浏览器上运行(但有时它会给我堆空间错误)。 如果有人知道如何正确地将文件发送到浏览器并正确地流式传输,我将是一个非常快乐的人


先谢谢你!:)

Emm。。。正如我所看到的,不管怎样,您都尝试在代码中使用块,
我记得,即使apache解决方案在从
BufferedInputStream
读取时也有文件大小限制,您可以允许其“缓冲区”处理缓冲,没有理由将所有内容都读取到整个文件的
字节[]
(当然也不是
字节[]
)。一次读取一个
字节
,并依赖流的内部缓冲区。大概

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

您似乎没有发送
内容长度
标题,我也没有看到
内容类型
。标题对HTTP来说相当重要。哦,我忘了把它添加到我的问题中。正在正确发送响应标题!我可以质疑代码的风格和一些细节,但从浏览器的角度来看,第二个版本的行为应该与第一个版本相同。请更具体地说明您所说的“好像文件字节正在被洗牌并一起发送到浏览器”的意思。这对疑难解答没有帮助。您用于写入数据的
write()
方法是什么?可能是有缺陷,只有在反复调用时才会出现。您不应该将整个文件读入缓冲区进行流式处理,使用缓冲,您应该一次读取和写入一个字节(并让缓冲区处理)。这实际上让它工作了Elliott,非常感谢:)