- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java编程实现服务器端支持断点续传的方法(可支持快车、迅雷)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了Java编程实现服务器端支持断点续传的方法。分享给大家供大家参考,具体如下:
大家知道Tomcat之流对静态资源可以实现断点续传支持,但是如果是一个被控制的流,如有权限控制,或下载地址仅是个代理的时候,这时候需要自己实现断点续传的支持,小弟不才,这里提供基本断点续传[a-,-b,a-b]的简单实现,经验证,可支持迅雷7和火狐的多次断点续传。现贴出代码,大家共同分享:
Servlet 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
import
java.io.BufferedOutputStream;
import
java.io.File;
import
java.io.IOException;
import
java.io.RandomAccessFile;
import
java.io.UnsupportedEncodingException;
import
java.net.URI;
import
java.net.URISyntaxException;
import
java.net.URLDecoder;
import
javax.servlet.ServletException;
import
javax.servlet.ServletOutputStream;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.bsteel.cloud.storage.servlet.base.BaseServlet;
import
com.bsteel.cloud.storage.utils.FileUtil;
/**
* 文件下载(支持断点续传【迅雷\快车\旋风\Firefox\Chrome】)
* @author jdkleo
*
*/
public
class
FileIoServlet
extends
BaseServlet {
private
static
final
long
serialVersionUID = 1L;
@Override
protected
void
doGet(HttpServletRequest req, HttpServletResponse resp)
throws
ServletException, IOException {
this
.doPost(req, resp);
}
@Override
protected
void
doPost(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException{
download(request,response);
}
/**
* 文件下载
* @param request
* @param response
* @throws UnsupportedEncodingException
*/
private
void
download(HttpServletRequest request,HttpServletResponse response)
throws
UnsupportedEncodingException {
File downloadFile = getFile(request);
long
pos = FileUtil.headerSetting(downloadFile, request, response);
// log.info("跳过"+pos);
ServletOutputStream os =
null
;
BufferedOutputStream out =
null
;
RandomAccessFile raf =
null
;
byte
b[] =
new
byte
[
1024
];
//暂存容器
try
{
os = response.getOutputStream();
out =
new
BufferedOutputStream(os);
raf =
new
RandomAccessFile(downloadFile,
"r"
);
raf.seek(pos);
try
{
int
n =
0
;
while
((n = raf.read(b,
0
,
1024
)) != -
1
) {
out.write(b,
0
, n);
}
out.flush();
}
catch
(IOException ie) {
}
}
catch
(Exception e) {
log.error(e.getMessage(), e);
}
finally
{
if
(out !=
null
) {
try
{
out.close();
}
catch
(IOException e) {
log.error(e.getMessage(), e);
}
}
if
(raf !=
null
) {
try
{
raf.close();
}
catch
(IOException e) {
log.error(e.getMessage(), e);
}
}
}
}
private
File getFile(HttpServletRequest request)
throws
UnsupportedEncodingException {
String uriStr = request.getParameter(
"uri"
);
if
(
null
!= uriStr){
uriStr = URLDecoder.decode(uriStr,
"UTF-8"
);
if
(uriStr.startsWith(
"file://"
)){
uriStr = uriStr.substring(
7
);
return
new
File(uriStr);
}
else
if
(uriStr.startsWith(
"hbase://"
)){
try
{
return
new
File(
new
URI(uriStr));
}
catch
(URISyntaxException e) {
log.error(e.getMessage(),e);
}
}
}
throw
new
RuntimeException(
"it's not a real uri"
);
}
}
|
Range支持 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
import
java.io.File;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
/**
* 文件处理工具
* @author jdkleo
*
*/
public
class
FileUtil {
/**
* 断点续传支持
* @param file
* @param request
* @param response
* @return 跳过多少字节
*/
public
static
long
headerSetting(File file,HttpServletRequest request, HttpServletResponse response) {
long
len = file.length();
//文件长度
if
(
null
== request.getHeader(
"Range"
) ){
setResponse(
new
RangeSettings(len),file.getName(),response);
return
0
;
}
String range = request.getHeader(
"Range"
).replaceAll(
"bytes="
,
""
);
RangeSettings settings = getSettings(len,range);
setResponse(settings,file.getName(),response);
return
settings.getStart();
}
private
static
void
setResponse(RangeSettings settings,String fileName, HttpServletResponse response) {
response.addHeader(
"Content-Disposition"
,
"attachment; filename=\""
+ IoUtil.toUtf8String(fileName) +
"\""
);
response.setContentType( IoUtil.setContentType(fileName));
// set the MIME type.
if
(!settings.isRange())
{
response.addHeader(
"Content-Length"
, String.valueOf(settings.getTotalLength()));
}
else
{
long
start = settings.getStart();
long
end = settings.getEnd();
long
contentLength = settings.getContentLength();
response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
response.addHeader(
"Content-Length"
, String.valueOf(contentLength));
String contentRange =
new
StringBuffer(
"bytes "
).append(start).append(
"-"
).append(end).append(
"/"
).append(settings.getTotalLength()).toString();
response.setHeader(
"Content-Range"
, contentRange);
}
}
private
static
RangeSettings getSettings(
long
len, String range) {
long
contentLength =
0
;
long
start =
0
;
long
end =
0
;
if
(range.startsWith(
"-"
))
// -500,最后500个
{
contentLength = Long.parseLong(range.substring(
1
));
//要下载的量
end = len-
1
;
start = len - contentLength;
}
else
if
(range.endsWith(
"-"
))
//从哪个开始
{
start = Long.parseLong(range.replace(
"-"
,
""
));
end = len -
1
;
contentLength = len - start;
}
else
//从a到b
{
String[] se = range.split(
"-"
);
start = Long.parseLong(se[
0
]);
end = Long.parseLong(se[
1
]);
contentLength = end-start+
1
;
}
return
new
RangeSettings(start,end,contentLength,len);
}
}
|
Range封装 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
public
class
RangeSettings{
private
long
start;
private
long
end;
private
long
contentLength;
private
long
totalLength;
private
boolean
range;
public
RangeSettings(){
super
();
}
public
RangeSettings(
long
start,
long
end,
long
contentLength,
long
totalLength) {
this
.start = start;
this
.end = end;
this
.contentLength = contentLength;
this
.totalLength = totalLength;
this
.range =
true
;
}
public
RangeSettings(
long
totalLength) {
this
.totalLength = totalLength;
}
public
long
getStart() {
return
start;
}
public
void
setStart(
long
start) {
this
.start = start;
}
public
long
getEnd() {
return
end;
}
public
void
setEnd(
long
end) {
this
.end = end;
}
public
long
getContentLength() {
return
contentLength;
}
public
void
setContentLength(
long
contentLength) {
this
.contentLength = contentLength;
}
public
long
getTotalLength() {
return
totalLength;
}
public
void
setTotalLength(
long
totalLength) {
this
.totalLength = totalLength;
}
public
boolean
isRange() {
return
range;
}
}
|
IO流相关处理工具类 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
import
java.io.InputStream;
public
class
IoUtil {
public
static
String setContentType(String returnFileName){
String contentType =
"application/octet-stream"
;
if
(returnFileName.lastIndexOf(
"."
) <
0
)
return
contentType;
returnFileName = returnFileName.toLowerCase();
returnFileName = returnFileName.substring(returnFileName.lastIndexOf(
"."
)+
1
);
if
(returnFileName.equals(
"html"
) || returnFileName.equals(
"htm"
) || returnFileName.equals(
"shtml"
)){
contentType =
"text/html"
;
}
else
if
(returnFileName.equals(
"css"
)){
contentType =
"text/css"
;
}
else
if
(returnFileName.equals(
"xml"
)){
contentType =
"text/xml"
;
}
else
if
(returnFileName.equals(
"gif"
)){
contentType =
"image/gif"
;
}
else
if
(returnFileName.equals(
"jpeg"
) || returnFileName.equals(
"jpg"
)){
contentType =
"image/jpeg"
;
}
else
if
(returnFileName.equals(
"js"
)){
contentType =
"application/x-javascript"
;
}
else
if
(returnFileName.equals(
"atom"
)){
contentType =
"application/atom+xml"
;
}
else
if
(returnFileName.equals(
"rss"
)){
contentType =
"application/rss+xml"
;
}
else
if
(returnFileName.equals(
"mml"
)){
contentType =
"text/mathml"
;
}
else
if
(returnFileName.equals(
"txt"
)){
contentType =
"text/plain"
;
}
else
if
(returnFileName.equals(
"jad"
)){
contentType =
"text/vnd.sun.j2me.app-descriptor"
;
}
else
if
(returnFileName.equals(
"wml"
)){
contentType =
"text/vnd.wap.wml"
;
}
else
if
(returnFileName.equals(
"htc"
)){
contentType =
"text/x-component"
;
}
else
if
(returnFileName.equals(
"png"
)){
contentType =
"image/png"
;
}
else
if
(returnFileName.equals(
"tif"
) || returnFileName.equals(
"tiff"
)){
contentType =
"image/tiff"
;
}
else
if
(returnFileName.equals(
"wbmp"
)){
contentType =
"image/vnd.wap.wbmp"
;
}
else
if
(returnFileName.equals(
"ico"
)){
contentType =
"image/x-icon"
;
}
else
if
(returnFileName.equals(
"jng"
)){
contentType =
"image/x-jng"
;
}
else
if
(returnFileName.equals(
"bmp"
)){
contentType =
"image/x-ms-bmp"
;
}
else
if
(returnFileName.equals(
"svg"
)){
contentType =
"image/svg+xml"
;
}
else
if
(returnFileName.equals(
"jar"
) || returnFileName.equals(
"var"
) || returnFileName.equals(
"ear"
)){
contentType =
"application/java-archive"
;
}
else
if
(returnFileName.equals(
"doc"
)){
contentType =
"application/msword"
;
}
else
if
(returnFileName.equals(
"pdf"
)){
contentType =
"application/pdf"
;
}
else
if
(returnFileName.equals(
"rtf"
)){
contentType =
"application/rtf"
;
}
else
if
(returnFileName.equals(
"xls"
)){
contentType =
"application/vnd.ms-excel"
;
}
else
if
(returnFileName.equals(
"ppt"
)){
contentType =
"application/vnd.ms-powerpoint"
;
}
else
if
(returnFileName.equals(
"7z"
)){
contentType =
"application/x-7z-compressed"
;
}
else
if
(returnFileName.equals(
"rar"
)){
contentType =
"application/x-rar-compressed"
;
}
else
if
(returnFileName.equals(
"swf"
)){
contentType =
"application/x-shockwave-flash"
;
}
else
if
(returnFileName.equals(
"rpm"
)){
contentType =
"application/x-redhat-package-manager"
;
}
else
if
(returnFileName.equals(
"der"
) || returnFileName.equals(
"pem"
) || returnFileName.equals(
"crt"
)){
contentType =
"application/x-x509-ca-cert"
;
}
else
if
(returnFileName.equals(
"xhtml"
)){
contentType =
"application/xhtml+xml"
;
}
else
if
(returnFileName.equals(
"zip"
)){
contentType =
"application/zip"
;
}
else
if
(returnFileName.equals(
"mid"
) || returnFileName.equals(
"midi"
) || returnFileName.equals(
"kar"
)){
contentType =
"audio/midi"
;
}
else
if
(returnFileName.equals(
"mp3"
)){
contentType =
"audio/mpeg"
;
}
else
if
(returnFileName.equals(
"ogg"
)){
contentType =
"audio/ogg"
;
}
else
if
(returnFileName.equals(
"m4a"
)){
contentType =
"audio/x-m4a"
;
}
else
if
(returnFileName.equals(
"ra"
)){
contentType =
"audio/x-realaudio"
;
}
else
if
(returnFileName.equals(
"3gpp"
) || returnFileName.equals(
"3gp"
)){
contentType =
"video/3gpp"
;
}
else
if
(returnFileName.equals(
"mp4"
) ){
contentType =
"video/mp4"
;
}
else
if
(returnFileName.equals(
"mpeg"
) || returnFileName.equals(
"mpg"
) ){
contentType =
"video/mpeg"
;
}
else
if
(returnFileName.equals(
"mov"
)){
contentType =
"video/quicktime"
;
}
else
if
(returnFileName.equals(
"flv"
)){
contentType =
"video/x-flv"
;
}
else
if
(returnFileName.equals(
"m4v"
)){
contentType =
"video/x-m4v"
;
}
else
if
(returnFileName.equals(
"mng"
)){
contentType =
"video/x-mng"
;
}
else
if
(returnFileName.equals(
"asx"
) || returnFileName.equals(
"asf"
)){
contentType =
"video/x-ms-asf"
;
}
else
if
(returnFileName.equals(
"wmv"
)){
contentType =
"video/x-ms-wmv"
;
}
else
if
(returnFileName.equals(
"avi"
)){
contentType =
"video/x-msvideo"
;
}
return
contentType;
}
// UTF8转码
public
static
String toUtf8String(String s) {
StringBuffer sb =
new
StringBuffer();
int
len = s.toCharArray().length;
for
(
int
i =
0
; i < len; i++) {
char
c = s.charAt(i);
if
(c >=
0
&& c <=
255
) {
sb.append(c);
}
else
{
byte
[] b;
try
{
b = Character.toString(c).getBytes(
"utf-8"
);
}
catch
(Exception ex) {
System.out.println(ex);
b =
new
byte
[
0
];
}
for
(
int
j =
0
; j < b.length; j++) {
int
k = b[j];
if
(k <
0
)
k +=
256
;
sb.append(
"%"
+ Integer.toHexString(k).toUpperCase());
}
}
}
String s_utf8 = sb.toString();
sb.delete(
0
, sb.length());
sb.setLength(
0
);
sb =
null
;
return
s_utf8;
}
public
static
InputStream skipFully(InputStream in,
long
howMany)
throws
Exception{
long
remainning = howMany;
long
len =
0
;
while
(remainning>
0
){
len = in.skip(len);
remainning -= len;
}
return
in;
}
}
|
注有些类比如IoUtil方法来自于CSDN的网友总结,另外此类还不支持多Range配置如[a-b,c-d,-e]等.
希望本文所述对大家Java程序设计有所帮助.
最后此篇关于Java编程实现服务器端支持断点续传的方法(可支持快车、迅雷)的文章就讲到这里了,如果你想了解更多关于Java编程实现服务器端支持断点续传的方法(可支持快车、迅雷)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
当我的测试用例挂起时,我设法生成了线程转储。但是,这似乎不是死锁、竞争条件或资源争用。但是在我的加载测试工具中使用 3 个虚拟用户运行测试用例时,它肯定会挂起。任何人都可以在这里指出我正确的方向吗?干
复制代码 代码如下: #!/usr/bin/perl use File::DirWalk; use File::Basename; use Data::Dumper; use warnings;
个人认为影响的原因: 匹配到的图片url并不是有效的url,文中只是简单的判断是否是相对路径,但是有些url是失效的 解决办法:就是新增判断是否是真实有效url的图片 复制代码
考虑到这个问题:Passing a Shapeless Extensible Record to a Function,Travis的答案表明,每个以可扩展记录为参数的函数都必须有一个隐式选择器作为参
我通过这样的套接字发送ascii: outputStreamWriter(s + (char) 13); outputStreamWriter.flush(); 在现场,flush() 和通过网络发送
在我们正在进行的重构练习中,我们必须更改选定网站的页面模板。大多数页面都被本地化并通过下面的代码更新了他们的页面模板,但对于一些我们得到以下错误: “名称、文件名对于以下类型的项目必须是唯一的:其结构
我知道已经有Default value on generic predicate as argument了。 但是,也许现在c++ 11,c++ 14或c++ 17有了新的选择? 我如何才能使这项工作
select sum(case when NumFirstNames <> 1 then 1 else 0 end) as DifferentFirstNames, sum(case when
我已将:根证书、中间证书、服务器证书导入 Tomcat for Windows 的 Java Keystore。 这些是 VeriSign(商业)证书.. 我们不能将 keyAlias 用于连接器 -
我的问题是基于这个问题:Correct way to inherit from a virtual class with non-virtual parent . 我的理解是否正确,在问题中描述的情况
我不确定是否需要使用像 PLINQ 这样的高级技术,因为我想重新表述我之前的问题 Paralleling trading software我认为我之前的问题太复杂而且不清楚,我希望现在我准确地提取了所
这是我在这里遇到的问题(仍未解决)的延续:link 但这可能有助于理解问题所在。我只创建了一个简单的测试项目('Empty Application')并添加了一个带有 XIB 文件的 View Con
好的,所以昨天我发布了一个关于创建一个模拟电影矩阵雨的 java jframe 的问题,我希望它就像这个 php 示例一样 http://mgccl.com/2007/03/30/simple-ver
从这个线程继续: What are good algorithms for vehicle license plate detection? 我开发了我的图像处理技术来尽可能强调车牌,总体而言我很满意
这个问题在我这里的问题上继续(根据 Mystical 的建议): C code loop performance 继续我的问题,当我使用打包指令而不是标量指令时,使用内部函数的代码看起来非常相似: f
这是 My Old Question 的延续 这是我创建一个新学生对象的函数: function student(id, name, marks, mob, home){ this.id =
建立在我的 last question我想弄清楚如何.local和 .comm指令准确地工作,特别是它们如何影响 C 中的链接和持续时间。 所以我进行了以下实验: static int value;
这个问题引用这个之前的one由 Christian Metzler 在 SO 上发布. 我唯一非常有限的关于注解的经验包括使用最近 Delphi 版本中引入的 CustomAttribute。 我的问
我正在使用 Jetty 和 Continuations 来实现长轮询,但我没有找到检测客户端断开连接的方法。 我知道,在第一次运行(创建 Continuation)和任何后续运行之间的时间里,由于 H
这是 CSS Display an Image Resized and Cropped 的延续.该用户的答案似乎没问题,但我需要一些帮助来改进该答案... 问:resize(缩放)如何在运行时与图像的
我是一名优秀的程序员,十分优秀!