用Java实现HTTP断点续传功能(2)

用Java实现HTTP断点续传功能(2),第1张

//启动子线程

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/27070

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

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版本是不支持的。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12292841.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存