//启动子线程
fileSplitterFetch = new FileSplitterFetch[nStartPos length]
for(int i= i&ltnStartPos lengthi++)
{
fileSplitterFetch[i] = new FileSplitterFetch(siteInfoBean getSSiteURL()
siteInfoBean getSFilePath() + File separator + siteInfoBean getSFileName()
nStartPos[i] nEndPos[i] i)
Utility log( Thread + i + nStartPos = + nStartPos[i] + nEndPos = + nEndPos[i])
fileSplitterFetch[i] start()
}
// fileSplitterFetch[nPos length ] = new FileSplitterFetch(siteInfoBean getSSiteURL()
siteInfoBean getSFilePath() + File separator + siteInfoBean getSFileName() nPos[nPos length ] nFileLength nPos length )
// Utility log( Thread + (nPos length ) + nStartPos = + nPos[nPos length ] +
nEndPos = + nFileLength)
// fileSplitterFetch[nPos length ] start()
//等待子线程结束
//int count =
//是否结束while循环
boolean breakWhile = false
while(!bStop)
{
write_nPos()
Utility sleep( )
breakWhile = true
for(int i= i&ltnStartPos lengthi++)
{
if(!fileSplitterFetch[i] bDownOver)
{
breakWhile = false
break
}
}
if(breakWhile)
break
//count++
//if(count&gt)
// siteStop()
}
System err println( 文件下载结束!察姿闷 )
册哪 }
catch(Exception e){e printStackTrace ()}
}
//获得文件长度
public long getFileSize()
{
int nFileLength =
try{
URL url = new URL(siteInfoBean getSSiteURL())
HttpURLConnection Connection = (HttpURLConnection)url openConnection ()
( User Agent NetFox )
int responseCode=()
if(responseCode&gt= )
{
processErrorCode(responseCode)
return // represent access is error
}
String sHeader
for(int i= i++)
败弯 {
//DataInputStream in = new DataInputStream( ())
//Utility log(in readLine())
sHeader=(i)
if(sHeader!=null)
{
if(sHeader equals( Content Length ))
{
nFileLength = Integer parseInt((sHeader))
break
}
}
else
break
}
}
catch(IOException e){e printStackTrace ()}
catch(Exception e){e printStackTrace ()}
Utility log(nFileLength)
return nFileLength
}
//保存下载信息(文件指针位置)
private void write_nPos()
{
try{
output = new DataOutputStream(new FileOutputStream(tmpFile))
output writeInt(nStartPos length)
for(int i= i&ltnStartPos lengthi++)
{
// output writeLong(nPos[i])
output writeLong(fileSplitterFetch[i] nStartPos)
output writeLong(fileSplitterFetch[i] nEndPos)
}
output close()
}
catch(IOException e){e printStackTrace ()}
catch(Exception e){e printStackTrace ()}
}
//读取保存的下载信息(文件指针位置)
private void read_nPos()
{
try{
DataInputStream input = new DataInputStream(new FileInputStream(tmpFile))
int nCount = input readInt()
nStartPos = new long[nCount]
nEndPos = new long[nCount]
for(int i= i&ltnStartPos lengthi++)
{
nStartPos[i] = input readLong()
nEndPos[i] = input readLong()
}
input close()
}
catch(IOException e){e printStackTrace ()}
catch(Exception e){e printStackTrace ()}
}
private void processErrorCode(int nErrorCode)
{
System err println( Error Code : + nErrorCode)
}
//停止文件下载
public void siteStop()
{
bStop = true
for(int i= i&ltnStartPos lengthi++)
fileSplitterFetch[i] splitterStop()
}
lishixinzhi/Article/program/Java/hx/201311/270701package 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
14public static void down(String URL, long nPos, String savePathAndFile) {
15try {
16URL url = new URL(URL)
17HttpURLConnection httpConnection = (HttpURLConnection) url
18.openConnection()
19// 设置User-Agent
20httpConnection.setRequestProperty("User-Agent", "NetFox")
21// 设置断点续传的开始位置档尺销
22httpConnection.setRequestProperty("RANGE", "bytes=" + nPos)
23// 获得输困帆入流
24InputStream input = httpConnection.getInputStream()
25RandomAccessFile oSavedFile = new RandomAccessFile(savePathAndFile,
26"rw")
27// 定位文件指针到nPos位置
28oSavedFile.seek(nPos)
29byte[] b = new byte[1024]
30int nRead
31/行游/ 从输入流中读入字节流,然后写到文件中
32while ((nRead = input.read(b, 0, 1024)) >0) {
33(oSavedFile).write(b, 0, nRead)
34}
35httpConnection.disconnect()
36} catch (MalformedURLException e) {
37e.printStackTrace()
38} catch (IOException e) {
39e.printStackTrace()
40}
41}
42
43public static long getRemoteFileSize(String url) {
44long size = 0
45try {
46HttpURLConnection conn = (HttpURLConnection) (new URL(url))
47.openConnection()
48size = conn.getContentLength()
49conn.disconnect()
50} catch (Exception e) {
51e.printStackTrace()
52}
53return size
54}
55
56public static void main(String[] args) {
57 String url = " http://www.videosource.cgogo.com/media/0/16/8678/8678.flv"
58String savePath = "F:\\"
59String fileName = url.substring(url.lastIndexOf("/"))
60String fileNam=fileName
61HttpURLConnection conn = null
62try {
63conn = (HttpURLConnection) (new URL(url)).openConnection()
64} catch (Exception e) {
65e.printStackTrace()
66}
67File file = new File(savePath + fileName)
68// 获得远程文件大小
69long remoteFileSize = getRemoteFileSize(url)
70System.out.println("远程文件大小="+remoteFileSize)
71int i = 0
72if (file.exists()) {
73// 先看看是否是完整的,完整,换名字,跳出循环,不完整,继续下载
74long localFileSize = file.length()
75System.out.println("已有文件大小为:"+localFileSize)
76
77if (localFileSize <remoteFileSize) {
78System.out.println("文件续传")
79down(url, localFileSize, savePath + fileName)
80}else{
81System.out.println("文件存在,重新下载")
82do{
83i++
84fileName = fileNam.substring(0, fileNam.indexOf(".")) + "(" + i
85+ ")" + fileNam.substring(fileNam.indexOf("."))
86
87file = new File(savePath + fileName)
88}while(file.exists())
89try {
90file.createNewFile()
91} catch (IOException e) {
92e.printStackTrace()
93}
94down(url, 0, savePath + fileName)
95}
96// 下面表示文件存在,改名字
97
98} else {
99try {
100file.createNewFile()
101System.out.println("下载中")
102down(url, 0, savePath + fileName)
103} catch (IOException e) {
104e.printStackTrace()
105}
106}
107}}
108
这个不太难吧?假设A给B传文件F(1024字节)。第一次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版本是不支持的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)