java断点续传
1. java 断点续传需要哪些jar包
Java-->实现断点续传(下载)
--> 断点续传: 就像迅雷下载文件一样,停止下载或关闭程序,下次下载时是从上次下载的地方开始继续进行,而不是重头开始...
--> RandomAccessFile --> pointer(文件指针) --> seek(移动文件指针) --> 断点续传
package com.dragon.java.downloadfile;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
/*
断点续传:对下载软件非常重要!
--> 第一次下载 100 字节
--> 第二次下载 101 字节...想办法知道上次从哪个地方断掉的。 上次已经下载到了什么位置。 记下断点的位置
------> 需要第三方的文件专门记住断点的位置
*/
public class Test {
public static void main(String args[]) {
File srcFile = new File("D:/Java4Android/01_Java考古学/01_Java考古学.mp4");
File desDir = new File("f:/vidio");
FileToDir(srcFile, desDir);
}
public static void FileToDir(File srcFile, File desDir) {
desDir.mkdirs();
// 创建配置文件
File configFile = new File(desDir, srcFile.getName().split("\\.")[0]
+ ".config");
// 创建目标文件
File desFile = new File(desDir, srcFile.getName());
if (!configFile.exists() && desFile.exists()) {
System.out.println("已下载过该文件!");
return;
}
RandomAccessFile rafSrc = null;
RandomAccessFile rafDes = null;
RandomAccessFile rafConfig = null;
try {
rafSrc = new RandomAccessFile(srcFile, "r");
rafDes = new RandomAccessFile(desFile, "rw");
rafConfig = new RandomAccessFile(configFile, "rw");
// 设置目标文件和源文件一样长
rafDes.setLength(srcFile.length());
// 设置配置的文件长度为8,防止第一次下载是出现EOF 异常
rafConfig.setLength(8);
// 从上次下载的位置开始继续下载!
long pointer = rafConfig.readLong();
System.out.println("已下载:" + ((float) pointer / srcFile.length())
* 100 + "%");
rafSrc.seek(pointer);
rafDes.seek(pointer);
// 单次传输长度设置小点,好观察是否断点续传
byte[] buffer = new byte[32];
int len = -1;
// 每次复制的开始,必须把源文件的指针和目标文件的指针从上次断开的位置去读
while ((len = rafSrc.read(buffer)) != -1) {
rafDes.write(buffer, 0, len);
// 在配置文件写的时候,每次使文件指针移动到最初的位置 --> 这样永远对只会存储前8个字节
rafConfig.seek(0);
// 每复制一次之和,赶紧记录下文件指针的位置,以备断点续传使用。
rafConfig.writeLong(rafSrc.getFilePointer());
}
} catch (IOException e) {
System.out.println(e);
} finally {
try {
rafSrc.close();
rafDes.close();
rafConfig.close();
} catch (IOException e) {
System.out.println(e);
}
// 在流关闭之后删除配置文件
System.out.println("下载成功!");
configFile.delete();
}
}
}
2. java socket数据流断点续传
设备往你这边传输数据时,你得知他的设备ID、数据的MD5校验值、操作授权代码。
传输数据开始,设备向你这边传输数据,你这边将受到的数据保存到文件或者数据库。传输过程中,你可能要告诉设备已经保存的数据字节数。
假如网络连接异常,按照你说的思路,发送心跳包检测连接情况。你这边程序将本次操作的数据保存、并将设备ID、数据MD5校验值、操作授权码、已保存的字节数保存到日志。
下次客户端请求续传,你就校验它的设备ID、操作授权代码,然后再告诉它从哪里开始续传,跳过那些字节。
续传完成,通知客户端,续传成功。
3. java ftp怎么实现java ftp方式的断点续传
运用类的办法,编程人员能够长途登录到FTP服务器,罗列该服务器上的目录,设置传输协议,以及传送文件。FtpClient类涵 盖了简直一切FTP的功用,FtpClient的实例变量保留了有关树立"署理"的各种信息。下面给出了这些实例变量:
public static boolean useFtpProxy
这个变量用于标明FTP传输过程中是不是运用了一个署理,因此,它实际上是一个符号,此符号若为TRUE,标明运用了一个署理主机。
public static String ftpProxyHost
此变量只要在变量useFtpProxy为TRUE时才有用,用于保留署理主机名。
public static int ftpProxyPort
此变量只要在变量useFtpProxy为TRUE时才有用,用于保留署理主机的端口地址。
FtpClient有三种不同方式的结构函数,如下所示:
1、public FtpClient(String hostname,int port)
此结构函数运用给出的主机名和端口号树立一条FTP衔接。
2、public FtpClient(String hostname)
此结构函数运用给出的主机名树立一条FTP衔接,运用默许端口号。
3、FtpClient()
此结构函数将创立一FtpClient类,但不树立FTP衔接。这时,FTP衔接能够用openServer办法树立。
一旦树立了类FtpClient,就能够用这个类的办法来翻开与FTP服务器的衔接。类ftpClient供给了如下两个可用于翻开与FTP服务器之间的衔接的办法。
public void openServer(String hostname)
这个办法用于树立一条与指定主机上的FTP服务器的衔接,运用默许端口号。
4. Java Socket如何实现文件的断点续传,有代码更好
上传:
上传时附带一个描述数据起始位置的参数。
接受的一端接收到数据后,按照起始位置续写文件。
下载:
按照本地已保存的大小,提交下载请求。
服务器按照请求的位置,传数据。
大概就是这么个意思。还要处理很多异常情况。
5. 用java向hdfs上传文件时,如何实现断点续传
@Component("javaLargeFileUploaderServlet")
@WebServlet(name = "javaLargeFileUploaderServlet", urlPatterns = { "/javaLargeFileUploaderServlet" })
public class UploadServlet extends HttpRequestHandlerServlet
implements HttpRequestHandler {
private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
@Autowired
UploadProcessor uploadProcessor;
@Autowired
FileUploaderHelper fileUploaderHelper;
@Autowired
ExceptionCodeMappingHelper exceptionCodeMappingHelper;
@Autowired
Authorizer authorizer;
@Autowired
StaticStateIdentifierManager staticStateIdentifierManager;
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException {
log.trace("Handling request");
Serializable jsonObject = null;
try {
// extract the action from the request
UploadServletAction actionByParameterName =
UploadServletAction.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.action));
// check authorization
checkAuthorization(request, actionByParameterName);
// then process the asked action
jsonObject = processAction(actionByParameterName, request);
// if something has to be written to the response
if (jsonObject != null) {
fileUploaderHelper.writeToResponse(jsonObject, response);
}
}
// If exception, write it
catch (Exception e) {
exceptionCodeMappingHelper.processException(e, response);
}
}
private void checkAuthorization(HttpServletRequest request, UploadServletAction actionByParameterName)
throws MissingParameterException, AuthorizationException {
// check authorization
// if its not get progress (because we do not really care about authorization for get
// progress and it uses an array of file ids)
if (!actionByParameterName.equals(UploadServletAction.getProgress)) {
// extract uuid
final String fileIdFieldValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId, false);
// if this is init, the identifier is the one in parameter
UUID clientOrJobId;
String parameter = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);
if (actionByParameterName.equals(UploadServletAction.getConfig) && parameter != null) {
clientOrJobId = UUID.fromString(parameter);
}
// if not, get it from manager
else {
clientOrJobId = staticStateIdentifierManager.getIdentifier();
}
// call authorizer
authorizer.getAuthorization(
request,
actionByParameterName,
clientOrJobId,
fileIdFieldValue != null ? getFileIdsFromString(fileIdFieldValue).toArray(new UUID[] {}) : null);
}
}
private Serializable processAction(UploadServletAction actionByParameterName, HttpServletRequest request)
throws Exception {
log.debug("Processing action " + actionByParameterName.name());
Serializable returnObject = null;
switch (actionByParameterName) {
case getConfig:
String parameterValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);
returnObject =
uploadProcessor.getConfig(
parameterValue != null ? UUID.fromString(parameterValue) : null);
break;
case verifyCrcOfUncheckedPart:
returnObject = verifyCrcOfUncheckedPart(request);
break;
case prepareUpload:
returnObject = prepareUpload(request);
break;
case clearFile:
uploadProcessor.clearFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));
break;
case clearAll:
uploadProcessor.clearAll();
break;
case pauseFile:
List<UUID> uuids = getFileIdsFromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));
uploadProcessor.pauseFile(uuids);
break;
case resumeFile:
returnObject =
uploadProcessor.resumeFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));
break;
case setRate:
uploadProcessor.setUploadRate(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)),
Long.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.rate)));
break;
case getProgress:
returnObject = getProgress(request);
break;
}
return returnObject;
}
List<UUID> getFileIdsFromString(String fileIds) {
String[] splittedFileIds = fileIds.split(",");
List<UUID> uuids = Lists.newArrayList();
for (int i = 0; i < splittedFileIds.length; i++) {
uuids.add(UUID.fromString(splittedFileIds[i]));
}
return uuids;
}
private Serializable getProgress(HttpServletRequest request)
throws MissingParameterException {
Serializable returnObject;
String[] ids =
new Gson()
.fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId), String[].class);
Collection<UUID> uuids = Collections2.transform(Arrays.asList(ids), new Function<String, UUID>() {
@Override
public UUID apply(String input) {
return UUID.fromString(input);
}
});
returnObject = Maps.newHashMap();
for (UUID fileId : uuids) {
try {
ProgressJson progress = uploadProcessor.getProgress(fileId);
((HashMap<String, ProgressJson>) returnObject).put(fileId.toString(), progress);
}
catch (FileNotFoundException e) {
log.debug("No progress will be retrieved for " + fileId + " because " + e.getMessage());
}
}
return returnObject;
}
private Serializable prepareUpload(HttpServletRequest request)
throws MissingParameterException, IOException {
// extract file information
PrepareUploadJson[] fromJson =
new Gson()
.fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.newFiles), PrepareUploadJson[].class);
// prepare them
final HashMap<String, UUID> prepareUpload = uploadProcessor.prepareUpload(fromJson);
// return them
return Maps.newHashMap(Maps.transformValues(prepareUpload, new Function<UUID, String>() {
public String apply(UUID input) {
return input.toString();
};
}));
}
private Boolean verifyCrcOfUncheckedPart(HttpServletRequest request)
throws IOException, MissingParameterException, FileCorruptedException, FileStillProcessingException {
UUID fileId = UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));
try {
uploadProcessor.verifyCrcOfUncheckedPart(fileId,
fileUploaderHelper.getParameterValue(request, UploadServletParameter.crc));
}
catch (InvalidCrcException e) {
// no need to log this exception, a fallback behaviour is defined in the
// throwing method.
// but we need to return something!
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
6. Java Socket如何实现文件的断点续传,有代码更好
1package com.tangshun.www.socket;
2
3import java.io.File;
4import java.io.IOException;
5import java.io.InputStream;
6import java.io.RandomAccessFile;
7import java.net.HttpURLConnection;
8import java.net.MalformedURLException;
9import java.net.URL;
10
11//断点续传
12public class DownLoad {
13
14 public static void down(String URL, long nPos, String savePathAndFile) {
15 try {
16 URL url = new URL(URL);
17 HttpURLConnection httpConnection = (HttpURLConnection) url
18 .openConnection();
19 // 设置User-Agent
20 httpConnection.setRequestProperty("User-Agent", "NetFox");
21 // 设置断点续传的开始位置
22 httpConnection.setRequestProperty("RANGE", "bytes=" + nPos);
23 // 获得输入流
24 InputStream input = httpConnection.getInputStream();
25 RandomAccessFile oSavedFile = new RandomAccessFile(savePathAndFile,
26 "rw");
27 // 定位文件指针到nPos位置
28 oSavedFile.seek(nPos);
29 byte[] b = new byte[1024];
30 int nRead;
31 // 从输入流中读入字节流,然后写到文件中
32 while ((nRead = input.read(b, 0, 1024)) > 0) {
33 (oSavedFile).write(b, 0, nRead);
34 }
35 httpConnection.disconnect();
36 } catch (MalformedURLException e) {
37 e.printStackTrace();
38 } catch (IOException e) {
39 e.printStackTrace();
40 }
41 }
42
43 public static long getRemoteFileSize(String url) {
44 long size = 0;
45 try {
46 HttpURLConnection conn = (HttpURLConnection) (new URL(url))
47 .openConnection();
48 size = conn.getContentLength();
49 conn.disconnect();
50 } catch (Exception e) {
51 e.printStackTrace();
52 }
53 return size;
54 }
55
56public static void main(String[] args) {
57 String url = " http://www.videosource.cgogo.com/media/0/16/8678/8678.flv";
58 String savePath = "F:\\";
59 String fileName = url.substring(url.lastIndexOf("/"));
60 String fileNam=fileName;
61 HttpURLConnection conn = null;
62 try {
63 conn = (HttpURLConnection) (new URL(url)).openConnection();
64 } catch (Exception e) {
65 e.printStackTrace();
66 }
67 File file = new File(savePath + fileName);
68 // 获得远程文件大小
69 long remoteFileSize = getRemoteFileSize(url);
70 System.out.println("远程文件大小="+remoteFileSize);
71 int i = 0;
72 if (file.exists()) {
73 // 先看看是否是完整的,完整,换名字,跳出循环,不完整,继续下载
74 long localFileSize = file.length();
75 System.out.println("已有文件大小为:"+localFileSize);
76
77 if (localFileSize < remoteFileSize) {
78 System.out.println("文件续传");
79 down(url, localFileSize, savePath + fileName);
80 }else{
81 System.out.println("文件存在,重新下载");
82 do{
83 i++;
84 fileName = fileNam.substring(0, fileNam.indexOf(".")) + "(" + i
85 + ")" + fileNam.substring(fileNam.indexOf("."));
86
87 file = new File(savePath + fileName);
88 }while(file.exists());
89 try {
90 file.createNewFile();
91 } catch (IOException e) {
92 e.printStackTrace();
93 }
94 down(url, 0, savePath + fileName);
95 }
96 // 下面表示文件存在,改名字
97
98 } else {
99 try {
100 file.createNewFile();
101 System.out.println("下载中");
102 down(url, 0, savePath + fileName);
103 } catch (IOException e) {
104 e.printStackTrace();
105 }
106 }
107 }}
108
7. java不用RandomAccessFile如何实现断点续传
断点续传不一定要RandomAccessFile,只要接收端告诉发送端已经接受到什么位置了,那么发送端就可以从这个位置开始往后读~然后读出来的数据给发送端就行了~
8. java实现ftp断点续传问题
//尝试移动文件内读取指针,实现断点续传
result
=
uploadFile(remoteFileName,
f,
ftpClient,
remoteSize);
//如果断点续传没有成功,则删除服务器上文件,重新上传
if(result
==
UploadStatus.Upload_From_Break_Failed){
if(!ftpClient.deleteFile(remoteFileName)){
return
UploadStatus.Delete_Remote_Faild;
}
result
=
uploadFile(remoteFileName,
f,
ftpClient,
0);
}
9. 关于JAVA断点续传
024字节)。第一次B接收了512字节,那么第二次连接A就应该从513字节开始传输。
也就是说,在第二次传输时,B要提供“我要从513字节开始传送文件F”的信息,然后A使用FileInputStream构建输入流读取本地文件,使用skip(512)方法跳过文件F的前512字节再传送文件,之后B将数据追加(append)到先前接收的文件末尾即可。
进一步考虑,如果要实现多线程传送,即分块传输,也同样的道理。假如B要求分作两块同时传输,那么A启动两个线程,一个从513字节读到768字节(工256字节),第二个线程从769字节到1024字节即可。
如果你要从网络上下载文件,就是说A方不是你实现的,那么你要先确认A方支不支持断电续传功能(HTTP1.1),然后你查阅下HTTP1.1协议,在HTTP1.1版本里,可以通过设置请求包头某个字段的信息(使用URLConnection创建连接并使用setRequestProperty(String key, String value) 方法设置)从而精确读取文件的某一段数据的。注意,基于HTTP断点续传的关键是1.1版本,1.0版本是不支持的。
补充:
嗯,查到了,是设置range属性,即setRequestProperty("range", "bytes=513-1024").你可以使用迅雷下载某个文件,然后从”线程信息“中就可以看到这个http1.1断点续传的所有行为信息了。
10. java web断点续传,我用的是fileupload来做的上传。
使用Struts2上传文件:
Struts文件上传需要使用File Upload Filter。Filter Upload Filter使用一些默认的规则:
Form中的<s:file name="image"></s:file>标签对应着Action类中的三个属性分别是:上传文件(java.io.File类型),文件名(java.lang.String类型),文件类型(java.lang.String类型,例如:image/jpeg)。命名规约为:
文件:名字与<s:file>标签中的name属性一致,这里为:image
文件名:文件 + FileName,这里为:imageFileName
文件类型:文件 + ContentType,这里为:imageContentType
所以针对上述<s:file name="image"></s:file>表示啊的上传文件的JSP和Action类被别为:
imageUpload.jsp:
[html]view plain
<%@pagecontentType="text/html;charset=UTF-8"language="java"%>
<%@taglibprefix="s"uri="/struts-tags"%>
<html>
<head><title>ImageUpload</title></head>
<body>
<h1>ImageUploadPage</h1>
<s:formaction="imageUpload"method="post"enctype="multipart/form-data">
<s:filename="image"></s:file>
<s:submit></s:submit>
</s:form>
</body>
</html>
packagecom.jpleasure;
importcom.opensymphony.xwork2.ActionSupport;
importjava.io.File;
importjava.io.InputStream;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
{
privateFileimage;
privateStringimageFileName;
privateStringimageContentType;
publicFilegetImage(){
returnimage;
}
publicvoidsetImage(Fileimage){
this.image=image;
}
publicStringgetImageFileName(){
returnimageFileName;
}
publicvoidsetImageFileName(StringimageFileName){
this.imageFileName=imageFileName;
}
(){
returnimageContentType;
}
publicvoidsetImageContentType(StringimageContentType){
this.imageContentType=imageContentType;
}
publicStringexecute(){
if(image!=null){
System.out.println("filenameis:"+this.imageFileName);
System.out.println("filecontenttypeis:"+this.imageContentType);
System.out.println("filelengthis:"+this.image.length());
}
returnSUCCESS;
}
}
<actionname="imageUpload"class="com.jpleasure.ImageUploadAction">
<result>/success.jsp</result>
</action>
packagecom.jpleasure;
importcom.opensymphony.xwork2.ActionSupport;
importjava.io.File;
importjava.io.InputStream;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
{
privateFileimage;
privateStringimageFileName;
privateStringimageContentType;
=null;
(){
returnimageInputStream;
}
publicvoidsetImageInputStream(InputStreamimageInputStream){
this.imageInputStream=imageInputStream;
}
publicFilegetImage(){
returnimage;
}
publicvoidsetImage(Fileimage){
this.image=image;
}
publicStringgetImageFileName(){
returnimageFileName;
}
publicvoidsetImageFileName(StringimageFileName){
this.imageFileName=imageFileName;
}
(){
returnimageContentType;
}
publicvoidsetImageContentType(StringimageContentType){
this.imageContentType=imageContentType;
}
publicStringexecute(){
if(image!=null){
System.out.println("filenameis:"+this.imageFileName);
System.out.println("filecontenttypeis:"+this.imageContentType);
System.out.println("filelengthis:"+this.image.length());
try{
this.imageInputStream=newFileInputStream(image);
}catch(FileNotFoundExceptione){
e.printStackTrace();
}
}
returnSUCCESS;
}
}
<actionname="imageUpload"class="com.jpleasure.ImageUploadAction">
<resultname="success"type="stream">
<paramname="contentType">image/pjpeg</param>
<paramname="inputName">imageInputStream</param>
<paramname="contentDisposition">attachment;filename="image.jpg"</param>
<paramname="bufferSize">1024</param>
</result>
</action>
<struts>
<packagename="myPackage"extends="struts-default">
<interceptor-refname="fileUpload">
<paramname="maximumSize">2MB</param>
<paramname="allowedTypes">text/html,image/jpeg</param>
</interceptor-ref>
<interceptor-refname="basicStack"/>
<actionname="imageUpload"class="com.jpleasure.ImageUploadAction">
<resultname="success"type="stream">
<paramname="contentType">image/pjpeg</param>
<paramname="inputName">imageInputStream</param>
<paramname="contentDisposition">
attachment;filename="image.jpg"
</param>
<paramname="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
ImageUploadAction.java:
[html]view plain
Struts.xml配置文件:
[html]view plain
这样当我们选中上传文件,提交的时候:文件内容会以File类型的方式放在image声明的变量中。文件的名字将会被放在imageFileName命名的变量中,文件的类型被放在imageContentType命名的变量中。
文件下载:
文件下载需要使用一个特殊的Result,stream类型的Result。Stream类型的Result主要用来处理文件下载操作。
处理原理为:所有的下载文件都是将一个二进制的流写入到HttpResponse中去。在Action类中定义一个InputSream类型的二进制流,在Result返回给用户的时候返回给用户。
扩展上述的代码,将上传来的文件直接下载给用户:
ImageUploadAction中需要追加一个InputSream类型的对象,并且指向上传的文件,代码如下,红色部分表示变化:
[html]view plain
配置文件为,红色为变化部分:
[html]view plain
ContentType表示下载文件的类型。
InputName表示Action类中用来下载文件的字段的名字。
ContentDisposition用来控制文件下载的一些信息,包括是否打开另存对话框,下载文件名等。
BufferSize表示文件下载时使用的缓冲区的大小。
实际项目开发的考虑:
控制上传文件的类型和最大允许上传文件的size
使用File Upload Intercepter的参数可盈控制上传文件的类型和最大允许上传文件的size。例如:
[html]view plain
上述表示允许上传jpeg和html类型的文件,且最大文件上传size为2MB
显示错误信息:
可以使用如下key表示的message来显示文件上传出错的提示信息:
消息Key 说明
struts.messages.error.uploading 文件无法正常上传时的公共错误
struts.messages.error.file.too.large 文件大小超过最大允许size时的错误提示
struts.messages.error.content.type.not.allowed 文件类型不在上传文件允许类型中的错误提示