您的位置:首页 > 编程语言 > Java开发

Java 下载超过2GB的文件

2013-12-02 21:05 393 查看
Java 下载超过2GB的文件
I discovered a few days back an issue with our product on HTTP downloads > 2GB.

It appears to be a simple overflow on the HttpServletResponse.setContentLength method.

You can probably excuse the API designers circa 1997 assuming a 32-bit signed Integer with

max value 231-1 (2147483647 bytes) would be sufficient. The Gigabit ethernet standard did not

come for another year (1998)!
Here is the exception seen when you provide a long value greater than 2147483647 bytes to

the setContentLength(int) method:
java.net.ProtocolException: Exceeded stated content-length of: '-XXXX' bytes

at weblogic.servlet.internal.ServletOutputStreamImpl.checkCL(ServletOutputStreamImpl.java:200)
Below is a sample download servlet with workaround for the 2gb limitation.

It has been tested on Firefox 3.6 against WebLogic Server 10.3.6 with a 2.2GB download and worked perfectly.

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;
import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class DownloadServlet

extends HttpServlet

{

@SuppressWarnings("compatibility:1533750721037291976")

private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

doPost(request, response);

}
protected void doPost(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

// if no file parameter specified, download hosts file

String file = request.getParameter("file");

file = (file == null || file.length() == 0) ? "/etc/hosts" : file;
File fileObj = new File(file);

if ((!fileObj.exists()) || (!fileObj.isFile()) || (!fileObj.canRead()))

{

throw new IOException("'file' '" + file + "' cannot be read.");

}
ServletContext context = getServletConfig().getServletContext();
String mimetype = context.getMimeType(file);

response.setContentType(mimetype == null ? "application/octet-stream" :

mimetype);

long length = fileObj.length();

if (length <= Integer.MAX_VALUE)

{

response.setContentLength((int)length);

}

else

{

response.addHeader("Content-Length", Long.toString(length));

}
response.setHeader("Content-Disposition",

"attachment; filename=\"" + fileObj.getName() + "\"");
ServletOutputStream out = response.getOutputStream();

InputStream in = null;

byte[] buffer = new byte[32768];

try

{

in = new FileInputStream(fileObj);
int bytesRead;

while ((bytesRead = in.read(buffer)) >= 0)

{

out.write(buffer, 0, bytesRead);

}

}

finally

{

if (in != null)

{

in.close();

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: