//尝试移动文件内读取指针,实现断点续传
创新互联从2013年创立,先为绥芬河等服务建站,绥芬河等地企业,进行企业商务咨询服务。为绥芬河企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
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);
}
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断点续传的所有行为信息了。
断点设置方法,当有临时文件时,直接在临时文件中读取上次中断时的断点位置。没有临时文件,即第一次时,重新设置断点。
rantmpfile.seek()跳转到一个位置的目的是为了让各个断点存储的位置尽量分开。
1package com.tangshun.;
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 = " ";
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