我有以下代码(Server是Tomcat/Linux)。
//通过当前HTTP连接发送本地文件
FileInputStream fin =新FileInputStream(sendFile);int readBlockSize;int totalBytes=0;while ((readBlockSize=fin.available())>0) { byte[]缓冲器=新bytereadBlockSize;fin.read(缓冲器,0,readBlockSize);outStream.write(缓冲区,0,readBlockSize);totalBytes+=readBlockSize;}
在我附加调试器时,使用3gp类型的一些文件,如下所示:
OutStream.write(缓冲液,0,readBlockSize);
它使用以下错误显示时间: ApplicationFilterChain.internalDoFilter(ServletRequest,ServletResponse)行:299并没有为文件提供服务。
有什么线索吗?谢谢A.K。
发布于 2010-10-20 16:42:27
您不能保证InputStream.read(byte[],int,int)实际读取所需的字节数:它可能读得更少。即使你打电话到available(),也无法提供这种保证。您应该使用来自fin.read的返回值来找出实际读取的字节数,并且只将这么多字节写入输出。
我猜你看到的问题可能与此有关。如果块读取小于可用大小,则缓冲区将被部分填充,当您将过多字节写入输出时将导致问题。
另外,不要每次通过循环分配一个新数组!这将导致大量不必要的内存分配,这将减缓代码的速度,如果OutOfMemoryError返回大量内存,则可能导致available()。
试试这个:
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;
}发布于 2010-10-20 16:50:21
避免这些类型的问题是我从Commons开始的原因。如果这是一个选项,您的代码如下所示。
FileInputStream fin = new FileInputStream(sendFile);
int totalBytes = IOUtils.copy(fin, outStream);不用再发明轮子了。
发布于 2010-10-20 16:38:53
可能.read()调用返回的字节比您请求的要少。这意味着您需要使用.read()的te返回值作为.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;
}https://stackoverflow.com/questions/3980086
复制相似问题