public class MyServlet extends HttpServlet { /**
*
*/
private static final long serialVersionUID = -72959383420152113L;
public MyServlet() {
super();
} public void destroy() {
super.destroy();
} public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String clientIp = request.getRemoteAddr();
String servletPara = request.getQueryString();// 得请求中的servlet参数
String id = request.getParameter("id");
//String realpath = listid(id);
File file = new File("d:\\法务大管家.rar");
boolean isNewDown = true;
try {
response.setContentType("APPLICATION/OCTET-STREAM;charset=GBK"); response.setHeader("Content-Disposition",
"attachment; filename=\"" + new String(file.getName().getBytes("gb2312"),"iso-8859-1") + "\"");
ServletOutputStream out = response.getOutputStream();
System.out.println(file.length()/1024);
ArrayList<Range> ranges = parseRange(request, response, (int) file.length());
if (ranges != null && ranges.size() > 0) {
// Partial content response. response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { Range range = (Range) ranges.get(0);
response.addHeader("Content-Range", "bytes " + range.start
+ "-" + range.end + "/" + range.length);
long length = range.end - range.start + 1;
if (length < Integer.MAX_VALUE) {
response.setContentLength((int) length);
} else {
// Set the content-length as String to be able to use a
// long
response.setHeader("content-length", "" + length);
} continueDown(out, file, range); isNewDown = false;
} else {
System.out.println("ranges.size() > 1");
}
}else if (isNewDown) {// 新的下载
response.setContentLength((int) file.length());
newDown(out, file, clientIp, servletPara, id);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} return;
} private void continueDown(ServletOutputStream out, File file, Range range)
throws FileNotFoundException, IOException { RandomAccessFile raf = new RandomAccessFile(file, "r");
raf.seek(range.start);
byte[] bBuf = new byte[1024];
int rLen = 0;
while ((rLen = raf.read(bBuf)) > 0) {
//System.out.println("continueDown中的rLen" + rLen);
out.write(bBuf, 0, rLen);
}
} private void newDown(ServletOutputStream out, File file, String clientIp,
String servletPara, String id) {// 新的下载
Date beginTime = new Date();
double toClientTime;//总够用的时间
String saveTime=null;//转换后的时间
String isOver=null; //下载是否完成
int downloadSize = 0;
int sum = 0;
try {
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufInput = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufOut = new BufferedOutputStream(out);
byte[] buff = new byte[2048];
int bytesRead;
try {
while (-1 != (bytesRead = bufInput.read(buff, 0, buff.length))) {
sum = sum + bytesRead;
bufOut.write(buff, 0, bytesRead);//出错地方
}
downloadSize=1;
} catch (IOException e) {
e.printStackTrace();
}
fileInputStream.close();
bufOut.close();
out.close();
toClientTime=(new Date().getTime()-beginTime.getTime())/1000.0; //下载一共用了多少时间
int hours=(int)toClientTime/3600;
int minute=(int)toClientTime%3600/60;
int second=(int)toClientTime%3600%60;
saveTime=hours+"时"+minute+"分"+second+"秒";
if(downloadSize!=0){
isOver="完成";
System.out.println("下载完成");
////update count down
}else{
isOver="未完成";
System.out.println("下载未完成 一共下载的大小为"+sum);
}
//IptoCountry iptocountry=new IptoCountry();
//iptocountry.insertTable(clientIp, servletPara, isOver,saveTime);
} catch (IOException e) {
e.printStackTrace();
}
} protected class Range { public long start; public long end; public long length; /**
* Validate range.
*/
public boolean validate() {
if (end >= length)
end = length - 1;
return ((start >= 0) && (end >= 0) && (start <= end) && (length > 0));
} public void recycle() {
start = 0;
end = 0;
length = 0;
} } /**
* Parse the range header.
*
* @param request
* The servlet request we are processing
* @param response
* The servlet response we are creating
* @return Vector of ranges
*/
protected ArrayList<Range> parseRange(HttpServletRequest request,
HttpServletResponse response, int fileLength) throws IOException { // long fileLength = resourceAttributes.getContentLength(); if (fileLength == 0)
return null; // Retrieving the range header (if any is specified
String rangeHeader = request.getHeader("Range");
System.out.println("arraylist中的rangeheader" + rangeHeader); if (rangeHeader == null)
return null;
// bytes is the only range unit supported (and I don't see the point
// of adding new ones).
if (!rangeHeader.startsWith("bytes")) {
response.addHeader("Content-Range", "bytes */" + fileLength);
response
.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
} rangeHeader = rangeHeader.substring(6);
System.out.println("arraylist中的rangeheader2" + rangeHeader); // Vector which will contain all the ranges which are successfully
// parsed.
ArrayList<Range> result = new ArrayList<Range>();
StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ","); // Parsing the range list
while (commaTokenizer.hasMoreTokens()) {
String rangeDefinition = commaTokenizer.nextToken().trim(); Range currentRange = new Range();
currentRange.length = fileLength; int dashPos = rangeDefinition.indexOf('-'); if (dashPos == -1) {
response.addHeader("Content-Range", "bytes */" + fileLength);
response
.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
} if (dashPos == 0) { try {
long offset = Long.parseLong(rangeDefinition);
currentRange.start = fileLength + offset;
currentRange.end = fileLength - 1;
} catch (NumberFormatException e) {
response
.addHeader("Content-Range", "bytes */" + fileLength);
response
.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
} } else { try {
currentRange.start = Long.parseLong(rangeDefinition
.substring(0, dashPos));
if (dashPos < rangeDefinition.length() - 1)
currentRange.end = Long.parseLong(rangeDefinition
.substring(dashPos + 1, rangeDefinition
.length()));
else
currentRange.end = fileLength - 1;
} catch (NumberFormatException e) {
response
.addHeader("Content-Range", "bytes */" + fileLength);
response
.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
} } if (!currentRange.validate()) {
response.addHeader("Content-Range", "bytes */" + fileLength);
response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return null;
} result.add(currentRange);
} return result;
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
} public void init() throws ServletException {
super.init();
}}
解决方案 »
- 请问为什么JPA里没有双向的多对一的映射模式?
- 超市收银系统开发用什么语言好呢?
- 开发过jmx应用的进来一下~~~~
- 调用不正确。。没理由啊
- 邮件的getMessage调用后,报错MethodNotSupportedException: getMessage
- #配置Struts,过不去了
- 这个错误捕捉不到
- javaEE中泛型service层怎么注入多个dao求解,感激不尽
- tomcat和servlet的关系衍生出来的问题,求大神指点!
- 如果循环中嵌套了递归,怎么取出所有的数据啊~
- ibatis中查询操作时想传入整型参数,怎么办.我用queryForObiect/List都不能传入整形参数
- 收购正则表达式一个
Connection reset by peer的原因:
经常出现的Connection reset by peer: 原因可能是多方面的,不过更常见的原因是:
①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
②:客户关掉了浏览器,而服务器还在给客户端发送数据;
③:浏览器端按了Stop
2G以下又没有问题
那就将超过2g的文件
每2G就自动作为一个断点呗
response.setContentLength((int) length);
} else {
// Set the content-length as String to be able to use a
// long
response.setHeader("content-length", "" + length);
}而在从头传的分支里却只有: }else if (isNewDown) {// 新的下载
response.setContentLength((int) file.length());
newDown(out, file, clientIp, servletPara, id);
}
改成如下代码看看是否ok }else if (isNewDown) {// 新的下载
if (length < Integer.MAX_VALUE) {
response.setContentLength((int) length);
} else {
response.setHeader("content-length", "" + length);
}
newDown(out, file, clientIp, servletPara, id);
}
每次下载的文件最大为2G,超过
2G的部分,就像是用户没下载完
一样,作相同的处理,进行续传
不就好了?而且,你也可以试试
把你的流flush一下,貌似你把
整个文件都写入缓存却没刷新过
吧,你本机的内存也就2G上下吧
呵呵