java的http断点续传原理(二)
- 格式:docx
- 大小:17.95 KB
- 文档页数:13
⽤Java实现断点续传(HTTP)在web项⽬中上传⽂件夹现在已经成为了⼀个主流的需求。
在OA,或者企业ERP系统中都有类似的需求。
上传⽂件夹并且保留层级结构能够对⽤户⾏成很好的引导,⽤户使⽤起来也更⽅便。
能够提供更⾼级的应⽤⽀撑。
数据表结构⽂件⽂件夹数据表结构⽂件数据表结构该项⽬核⼼就是⽂件分块上传。
前后端要⾼度配合,需要双⽅约定好⼀些数据,才能完成⼤⽂件分块,我们在项⽬中要重点解决的以下问题。
* 如何分⽚;* 如何合成⼀个⽂件;* 中断了从哪个分⽚开始。
如何分,利⽤强⼤的js库,来减轻我们的⼯作,市场上已经能有关于⼤⽂件分块的轮⼦,虽然程序员的天性曾迫使我重新造轮⼦。
但是因为时间的关系还有⼯作的关系,我只能罢休了。
最后我选择了百度的WebUploader来实现前端所需。
如何合,在合之前,我们还得先解决⼀个问题,我们如何区分分块所属那个⽂件的。
刚开始的时候,我是采⽤了前端⽣成了唯⼀uuid来做⽂件的标志,在每个分⽚请求上带上。
不过后来在做秒传的时候我放弃了,采⽤了Md5来维护分块和⽂件关系。
在服务端合并⽂件,和记录分块的问题,在这⽅⾯其实⾏业已经给了很好的解决⽅案了。
参考迅雷,你会发现,每次下载中的时候,都会有两个⽂件,⼀个⽂件主体,另外⼀个就是⽂件临时⽂件,临时⽂件存储着每个分块对应字节位的状态。
⽂件夹准备逻辑这些都是需要前后端密切联系才能做好,前端需要根据固定⼤⼩对⽂件进⾏分⽚,并且请求中要带上分⽚序号和⼤⼩。
前端发送请求顺利到达后台后,服务器只需要按照请求数据中给的分⽚序号和每⽚分块⼤⼩(分⽚⼤⼩是固定且⼀样的)算出开始位置,与读取到的⽂件⽚段数据,写⼊⽂件即可。
为了便于开发,我将服务端的业务逻辑进⾏了如下划分,分成初始化,块处理,⽂件上传完毕等。
服务端的业务逻辑模块如下功能分析:⽂件夹⽣成模块⽂件夹上传完毕后由服务端进⾏扫描代码如下初始化⽂件的逻辑初始化⽂件夹的逻辑保存⽂件(将⽂件信息写⼊到数据库)逻辑写⼊⽂件夹的逻辑分块上传,分块处理逻辑应该是最简单的逻辑了,up6已经将⽂件进⾏了分块,并且对每个分块数据进⾏了标识,这些标识包括⽂件块的索引,⼤⼩,偏移,⽂件MD5,⽂件块MD5(需要开启)等信息,服务端在接收这些信息后便可以⾮常⽅便的进⾏处理了。
用Java实现HTTP断点续传功能.2007年06月25日星期一16:13(一)断点续传的原理其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。
打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:假设服务器域名为,文件名为down.zip。
GET /down.zip HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, */*Accept-Language: zh-cnAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)Connection: Keep-Alive服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下200Content-Length=106786028Accept-Ranges=bytesDate=Mon, 30 Apr 2001 12:56:11 GMTETag=W/"02ca57e173c11:95b"Content-Type=application/octet-streamServer=Microsoft-IIS/5.0Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT所谓断点续传,也就是要从文件已经下载的地方开始继续下载。
所以在客户端浏览器传给Web服务器的时候要多加一条信息--从哪里开始(客户端提供一个文件偏移)。
下面是用自己编的一个"浏览器"来传递请求信息给Web服务器,要求从2000070字节开始。
http断点续传的原理
——————————————先讲原理,如下:——————————————————
举⼀个详细的例⼦:
⼀般场景,要访问的域名:,⽂件名为down.zip
服务器到请求后,按要求寻找请求的⽂件,提取⽂件的信息,然后返回给浏览器,返回信息如下
好了。
现在讲解⼀下断点续传原理:
所谓断点续传,也就是要从⽂件已经下载的地⽅开始继续下载。
因此,在客户端,浏览器传给web服务器的时候要多加⼀条信息--从哪⾥开始。
⽐⽅说,“浏览器”来传递请求信息给服务器,要求从2000070字节开始:
range: bytes=2000070- 这个就是浏览器对服务器喊话:“喂!服务器,down.zip这个⽂件从2000070字节开始传过来!前⾯的字节不⽤传了哈~”
服务器说:“好嘞!您等着~”,返回如下(返回的代码也改为206了,⽽不再是200了):
——————————————原理到此结束——————————————————。
java断点续传原理与实现Java的断点续传是一种实现大文件传输的技术,当传输过程中出现中断或者网络故障时,可以通过断点续传的机制,继续传输文件,而无需重新开始传输。
在传统的文件传输过程中,当文件传输失败时,重新传输整个文件是耗费时间和资源的。
而断点续传则通过记录传输的状态信息,使得在传输中断后可以从断点处继续传输,大大提高了传输效率。
断点续传的实现原理主要涉及到两个方面:状态信息记录和传输的恢复。
首先,要实现断点续传,我们需要记录传输过程的状态信息,包括文件的已传输大小、传输的起始位置等。
可以使用文件的元数据信息或者自定义的记录方式来实现。
这些状态信息通常会储存在服务器或者本地文件系统中。
其次,当传输中断后,需要根据之前记录的状态信息来恢复传输。
在Java中,可以通过读取之前保存的状态信息来确定传输的起始位置,然后从该位置处继续传输。
通过使用Java的文件输入输出流和字节流,可以实现断点续传功能。
具体实现中,可以使用Java的RandomAccessFile类来实现文件的读写操作。
通过设置文件的偏移量,可以从指定位置读取和写入数据。
这样,在断点续传时,我们只需要根据之前记录的起始位置,设置文件的偏移量,即可从断点处继续传输文件。
在实际应用中,我们可以将断点续传功能与HTTP协议结合使用,通过HTTP的Range请求头来实现断点续传功能。
在客户端发送请求时,可以通过设置Range头,指定文件传输的起始位置和结束位置。
服务器在接收到该请求后,根据指定的范围返回相应的文件片段。
这样,当传输中断后,客户端只需要再次发送带有Range头的请求,即可从中断处恢复传输。
总结起来,Java的断点续传通过记录传输状态信息和根据状态信息进行传输的恢复,实现了在传输中断后继续传输文件的功能。
通过合理运用Java的文件操作和网络传输技术,可以实现稳定高效的大文件传输,并在网络传输不稳定的情况下提供了更好的用户体验。
如果想要实现断点续传功能,可以按照上述原理和实现方法进行开发。
JA V A实现HTTP断点续传(一)断点续传的原理其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。
打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:假设服务器域名为,文件名为down.zip。
GET /down.zip HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, */*Accept-Language: zh-cnAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)Connection: Keep-Alive服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下:200Content-Length=106786028Accept-Ranges=bytesDate=Mon, 30 Apr 2001 12:56:11 GMTETag=W/"02ca57e173c11:95b"Content-Type=application/octet-streamServer=Microsoft-IIS/5.0Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT所谓断点续传,也就是要从文件已经下载的地方开始继续下载。
所以在客户端浏览器传给Web服务器的时候要多加一条信息--从哪里开始。
下面是用自己编的一个"浏览器"来传递请求信息给Web服务器,要求从2000070字节开始。
GET /down.zip HTTP/1.0User-Agent: NetFoxRANGE: bytes=2000070-Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2仔细看一下就会发现多了一行RANGE: bytes=2000070-;这一行的意思就是告诉服务器down.zip这个文件从2000070字节开始传,前面的字节不用传了。
断点续传方案简介断点续传是指在网络传输过程中,当连接中断或者文件传输中止时,能够从中断处重新开始传输,而不是从头开始。
这样可以提高文件传输的可靠性和传输效率。
在实际应用中,断点续传方案常常用于大文件的上传或下载过程中,以确保用户在网络不稳定的情况下能够顺利完成文件传输,而无需重新开始。
本文将介绍几种常见的断点续传方案,并分析各种方案的优缺点,帮助读者选择适合自己应用场景的方案。
方案一:基于HTTP的断点续传HTTP协议是应用层协议中最常用的协议之一,支持断点续传的HTTP服务器通常会在响应头中添加Range字段,用于指定服务器传输的起始位置。
客户端在进行文件下载时,通过设置请求头中的Range字段来请求指定范围的数据。
服务器接收到请求后,根据Range字段返回相应的数据片段。
如果客户端在下载过程中中断,可以通过设置Range字段重新发送请求,从中断处继续下载。
HTTP的断点续传方案具有以下优点:-:基于HTTP的断点续传方案使用标准的HTTP协议,不需要额外的协议和框架支持,方便快捷。
-:基于HTTP的断点续传方案通常兼容多种操作系统和终端设备,使用广泛。
-:通过设置不同的Range字段,可以实现下载指定范围的数据,具有较高的灵活性。
-:HTTP协议本身就具有较高的可靠性,断点续传方案在一定程度上增强了文件传输的可靠性。
然而,基于HTTP的断点续传方案也存在一些局限性:-:由于每次续传都需要从中断处开始,可能会导致重复传输已经传输过的数据,降低传输效率。
-:对于非常大的文件,服务器需要保存大量的中断点信息,占用较多的磁盘空间和内存资源。
-:如果服务器不支持断点续传,那么即使客户端实现了断点续传方案,也无法成功续传。
方案二:基于FTP的断点续传FTP(File Transfer Protocol)是一种文件传输协议,也常用于文件上传和下载。
FTP支持断点续传的机制,能够在网络中断或传输中止后从中断处继续传输。
利用Http协议实现断点续传利用Http协议实现断点续传朱爱梅摘要:本文介绍断点续传的原理和实现,并说明了如何利用Java语言通过Http协议实现断点续传功能的程序。
关键词:java;断点续传;序列化;流;Http协议;In ternet中图分类号:F123.16文献标识码:A文章编号:CN43-1027/F(2007)9-181-01作者:湖南科技职业学院软件学院;湖南,长沙,410006一、断点续传说明断点续传指当信号中断后(掉线或关机等),下次能够从上次中断地方开始接着传送(一般指下载或上传),不支持断点续传就意味着下次下载或上传必须从零开始,断点续传能提高下载的效率。
二、断点续传的实现。
11虽然断点续传的原理非常简单,但是在Internet上如何实现了?在Internet上,所有的连接都是无状态的,即当用户与服务器进行一次通信完成后,服务器将不再保留本次通信的状态与信息。
那么当文件从服务器下载到客户时,如果因为掉线或者关机,此时连接将被中断,下次开机后想继续下载,怎样才能恢复到上一次文件下载的位置了,如果不能恢复,则必须重新开始下载。
其实要解决这个问题也非常简单,通过对Http协议的分析后将会非常清楚。
21当客户与服务器在In ternet上通过Http协议进行联系时,客户首先向服务器发出请求,所发出的请求如下:假设服务器名为http://localhost/,请求的文件名为:mysite-2.rarGE T/mysite-2.rar HTTP/1.1Accep t:i mage/gif,i mage/x-xbitmap,image/jpeg,image/pjpeg,application/vnd.ms-excel,ap-plication/msword,application/vnd.ms-powerpoint,*/*Accep t-Language:zh-cn Accept-Encoding:gzip,deflate User-Agent: Mozilla/4.0(compatible;MSIE6.0;Windows NT5.0)Connection:Keep-Alive服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下: 200Content-Length=106786028Accept-Ranges=bytes Date= Wed,30May200711:56:11GMTETag=W//02ca57e173c11:95b0Content-Type=application/ octet-streamServer=Microsoft-IIS/6.0Last-Modified=Wed,30M ay 2007110:56:11GMT其中200表示连接正常。
java断点续传原理断点续传是指在网络传输过程中,当传输中断或失败后,能够从中断处继续传输,而不需要重新开始传输的一种技术。
在Java中实现断点续传主要依赖于HTTP协议和文件流操作。
HTTP协议是一种无连接的协议,每个请求和响应都是独立的。
当客户端发送请求时,服务器会返回一个状态码和文件的相关信息,如果状态码为206,则表示服务器支持部分内容传输,并返回相应的Content-Range头字段,用于指定从哪个字节到哪个字节的内容。
客户端根据这些信息可以知道文件已经传输到哪个位置,从而进行断点续传。
在Java中,可以使用URL类和HttpURLConnection类来实现HTTP连接和文件传输操作。
下面是一个简单的示例代码:```javaimport java.io.*;public class ResumeUploadExamplepublic static void main(String[] args)String savePath = "path/to/save/file";tryURL url = new URL(fileUrl);HttpURLConnection connection = (HttpURLConnection)url.openConnection(;File file = new File(savePath);long startPos = 0;if (file.exists()startPos = file.length(;connection.setRequestProperty("Range", "bytes=" + startPos + "-");}connection.connect(;int responseCode = connection.getResponseCode(;if (responseCode == HttpURLConnection.HTTP_PARTIAL)long contentLength = connection.getContentLengthLong(;InputStream inputStream = connection.getInputStream(;RandomAccessFile outputFile = new RandomAccessFile(file, "rw");outputFile.seek(startPos);byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1)outputFile.write(buffer, 0, bytesRead);}outputFile.close(;inputStream.close(;System.out.println("File downloaded successfully!");} elseSystem.out.println("Server does not support resume!");}} catch (IOException e)e.printStackTrace(;}}```在上述代码中,首先创建URL对象并打开HTTP连接。
java断点续传原理Java中的断点续传原理通常用于网络文件传输,即在文件传输过程中,可以在中断或终止的地方继续传输,而无需重新开始传输整个文件。
下面是详细的Java断点续传原理:1.文件分块:要实现断点续传,首先将要传输的文件划分为较小的块或片段。
这样做的目的是在传输过程中,可以只传输所需的文件块,而不必传输整个文件。
2.传输控制:使用网络编程库(如Java的Socket或HttpURLConnection类)在客户端和服务器端之间建立连接,以进行文件传输。
客户端和服务器端之间可以通过交换信息来控制文件的传输。
客户端可以向服务器发送请求,指示从哪个文件块开始传输。
3.传输记录:为了能够在断点处继续传输,需要记录上次传输的位置。
通常使用一个额外的文件或数据库来记录传输的状态。
在每次成功传输一个文件块后,将记录下次需要传输的文件块的位置。
4.传输异常处理:在文件传输过程中,可能会出现网络中断、传输错误或其他异常情况。
当发生这些异常时,客户端和服务器端可以根据传输记录来确定下一个需要传输的文件块,并重新建立连接继续传输。
这样可以避免重新传输已经成功传输的文件块。
5.完成传输:当所有文件块都成功传输并合并到服务器上的完整文件中时,可以认为文件传输已经完成。
可以根据需要在客户端和服务器端进行相应的操作,如关闭连接、进行文件校验等。
当实现Java断点续传时,还可以考虑以下几个方面:1. Range请求:在进行HTTP文件传输时,可以使用Range 请求头来指定从哪个位置开始传输文件。
服务器可以根据Range请求头确定需要传输的文件块范围,然后只传输该范围内的数据。
2. 断点续传请求:在传输中断后,客户端可以向服务器发送断点续传请求,请求从上次传输结束的地方继续传输。
服务器接收到请求后,根据传输记录找到需要传输的下一个文件块,并将其发送给客户端。
3. 文件校验:为了确保文件传输的完整性和准确性,可以在传输过程中进行文件校验。
Http多线程下载与断点续传分析找了很多天的工作,真是找得有点郁闷,也就惰了下来!发现现在的简历真是不值钱。
上次面试的时候本来投的是“高级程序员”职位,笔试也笔试,面试也面了。
本来还是信心满满的. 不过后来在谈到薪水的时候,被贬到了初级程序员,给的高级程序员标准我还达不到,中级程序员的标准也需要一定条件--中级证书,郁闷的是我也没有!最后被定位为初级程序员!还真是有点打击人。
不过我到现在也不知道初中高级程序员的标准究竟在哪里,平时总是尽量让自己提高,也很少去考滤到证书的重要性!总之最后就是泡汤了好了,口水就吐到这里吧,转入正题!投简历归投简历,剩余时间总是喜欢做一点自己喜欢做的事。
有时候发现最快乐的事就是静静的听着音乐,敲着代码,写一些东西与朋友一起分享,一起研究。
上次的- “Mp3在线搜索工具”还有很多可以改进的地方,也得到一些朋友的建议,非常感谢。
这个版本中加入了断点续传的功能,使用了XML文件保存任务列表及状态信息,并且支持多线程分段下载, 提高下载速度,在这一个版本中,我把它叫做: JLoading 因为我还想不出一个更好听一点或更酷一些的名字,而且我还想让他可以下载一些其它文件。
程序不想做大,但想做得极致一些,比如从速度上。
欢迎交流学习, huliqing(huliqing@)Jloading完整程序下载Jloading源码下载(仅供学习研究使用,有任何问题请与本人联系)协议针对于Http,先谈一下简单原理。
因为代码太多,在这里只取重点分析。
如果你对http协议比较了解,那么你应该已经知道原理了,只要在请求头中加入以下代码就可以只请求部分数据:Content-Range: bytes 20000-40000/47000 ,即从第20000字节请求到第40000个字节,(文件长度是47000字节).知道了这一点之后,请求数据就非常容易了,只要利用Java中的URL,先探测数据的长度,然后再将这个长度分片段进行多段程下载就可以了,以下是我的实现方式:// 对文件进行分块try {totalBytes = new URL(url).openConnection().getContentLength();if (totalBytes == -1) state = STATE_NONE;} catch (IOException ioe) {return;}// 创建分块,并创建相应的负责下载的线程long pieceSize = (long) Math.ceil((double) totalBytes / (double) threads);long pStart = 0;long pEnd = 0;tasksAll.clear();tasks.clear();for (int i = 0; i < threads; i++) {if (i == 0) {pStart = pieceSize * i;}if (i == threads - 1) {pEnd = totalBytes;} else {pEnd = pStart + pieceSize;}Piece piece = new Piece(pStart, pStart, pEnd);tasksAll.add(piece);tasks.add(piece);pStart = pEnd + 1;}程序根据线程数目划分成相应的分片信息(Piece)并放入任务列表中,由线程池中的线程去负责下载,每个线程负责一个片段(Piece),当线程下载完自己的分片之后并不立即消毁,而是到任务队列中继续获取任务,若任务池为空,则将自己放入空闲池中并等待新任务,其他线程在发现有空闲线程时,则将自己所负责的任务分片再进行切割,并放入到任务队列中,同时唤醒空闲线程帮助下载,这样不会出现懒惰线程,也可以实现动态增删线程的功能,注意的是一些线程同步的问题。
断点续传的原理-断点续传是一种常见的网络传输技术,它允许在网络传输过程中出现断开连接或其他中断情况后能够继续传输,并且能够从断点处继续传输,而不需要重新下载整个文件。
这项技术在提高文件传输效率的同时也能够节省用户的时间和网络资源。
下面将从深度和广度两个方面来探讨断点续传的原理。
一、深度探讨断点续传的原理1.1 HTTP协议的特点断点续传技术主要在HTTP协议的基础上实现。
而HTTP协议是一种无状态的协议,它是通过请求-响应模式来进行通信的。
当我们在浏览器上下载文件时,浏览器会向服务器发送一个HTTP请求,并且等待服务器的响应。
这种请求-响应模式使得当网络连接出现中断时,传输过程中的数据将无法继续传输。
1.2 断点续传的实现原理为了实现断点续传,服务器需要支持请求头中的Range属性。
当浏览器发起一个下载请求时,可以在请求头中添加Range属性来指定下载文件的起始位置。
服务器接收到该请求后,会从指定的位置开始传输文件数据,并在响应头中返回Content-Range属性,用于标识本次传输的文件范围。
1.3 下载管理器的实现断点续传还需要通过下载管理器来进行控制和管理。
下载管理器主要分为两个部分:下载器和断点续传管理器。
下载器负责处理网络连接、数据传输等底层操作,而断点续传管理器负责监测和记录文件传输情况,并在需要时将相关信息保存到本地。
二、广度探讨断点续传的应用和优势2.1 应用场景断点续传技术广泛应用于文件下载、视频播放等场景。
当用户在下载大文件时,如果下载过程中网络中断或者暂停了下载,断点续传技术能够从中断的地方继续传输,而不需要重新下载整个文件。
在视频播放中,断点续传技术也能够让用户随时停止和继续观看,提供更好的用户体验。
2.2 优势和价值断点续传技术的优势主要体现在以下几个方面:2.2.1 节省用户时间:当网络传输中断时,断点续传技术能够让用户从中断的地方继续传输,节省用户重新下载整个文件的时间。
很简单的Java断点续传实现原理原理解析在开发当中,“断点续传”这种功能很实⽤和常见,听上去也是⽐较有“逼格”的感觉。
所以通常我们都有兴趣去研究研究这种功能是如何实现的?以Java来说,⽹络上也能找到不少关于实现类似功能的资料。
但是呢,⼤多数都是举个Demo然后贴出源码,真正对其实现原理有详细的说明很少。
于是我们在最初接触的时候,很可能就是直接Crtl + C/V代码,然后捣⿎捣⿎,然⽽最终也能把效果弄出来。
但初学时这样做其实很显然是有好有坏的。
好处在于,源码很多,解释很少;如果我们肯下功夫,针对于别⼈贴出的代码⾥那些⾃⼰不明⽩的东西去查资料,去钻研。
最终多半会收获颇丰。
坏处也很明显:作为初学者,⾯对⼀⼤堆的源码,感觉好多东西都很陌⽣,就很容易望⽽⽣畏。
即使最终⼤致了解了⽤法,但也不⼀定明⽩实现原理。
我们今天就⼀起从最基本的⾓度切⼊,来看看所谓的“断点续传”这个东西是不是真的如此“⾼逼格”。
其实在接触⼀件新的“事物”的时候,将它拟化成⼀些我们本⾝⽐较熟悉的事物,来参照和对⽐着学习。
通常会事半功倍。
如果我们刚接触“断点续传”这个概念,肯定很难说清楚个⼀⼆三。
那么,“玩游戏”我们肯定不会陌⽣。
OK,那就假设我们现在有⼀款“通关制的RPG游戏”。
想想我们在玩这类游戏时通常会怎么做?很明显,第⼀天我们浴⾎奋战,⼤杀四⽅,假设终于来到了第四关。
虽然激战正酣,但⼀看墙上的时钟,已经凌晨12点,该睡觉了。
这个时候就很尴尬了,为了能够在下⼀次玩的时候,顺利接轨上我们本次游戏的进度,我们应该怎么办呢?很简单,我们不关掉游戏,直接去睡觉,第⼆天再接着玩呗。
这样是可以,但似乎总觉着有哪⾥让⼈不爽。
那么,这个时候,如果这个游戏有⼀个功能叫做“存档”,就很关键了。
我们直接选择存档,输⼊存档名“第四关”,然后就可以关闭游戏了。
等到下次进⾏游戏时,我们直接找到“第四关”这个存档,然后进⾏读档,就可以接着进⾏游戏了。
这个时候,所谓的“断点续传”就很好理解了。
JAVA支持HTTP断点续传文件下载是WEB网站提供的最基本服务,然而你知道HTTP的断点续传是怎么实现的吗?背景这两天在实现一个基于HTML5在线音视频播放,由于文件是存放于企业网盘中的,HTTP不可达,因此需要用程序来实现文件的读取和HTTP协议的下载。
用Java实现文件下载也不用多说了,读取文件,通过二进制流的方式往response里写就行了。
H5播放器调用也能进行播放了;然而当我控制进度的前进和后退时,问题来了,居然一点效果都没有!没有快进播放器还叫播放器吗?分析首先看到播放器无法取得音视频文件的时间长度,很自然想到Content-Length属性,后台通过file.length()取得文件长度并设置到Content-Length上(代码如下),前台播放器里可以显示音视频的长度了,并且可以快进了;然而当我快退的时候,还是无效,同时后台报错。
response.addHeader('Content-Length', file.length());换了一个HTTP文件进行比较测试,发现直接HTTP访问的能够正常快进快退。
仔细分析两者的request和response头,发现了区别,请求参数多了如下图所示属性,该属性表名需要从服务端获取的资源范围,默认从第一个字节开始取,快进快退实际上就是通过指定这个Range属性来确定你所期望的起始点。
然而这个属性是在请求头上的,客户端又是怎么知道要添加这个属性呢?继续寻找发现了Accept-Ranges这个属性,属性值是bytes,其表明是否接受获取其某个实体的一部分(比如文件的一部分)的请求。
bytes:表示接受,none:表示不接受。
与此对应的response中另外一个属性Content-Range,其表名该响应包含的部分对象为整个对象的哪个部分。
完整响应头如下:解决根据上面的分析,我们就知道在服务端该怎么处理了,首先在响应头上添加Accept-Ranges。
11600字Java多线程与线程安全实践——基于Http协议的断点续传摘要现实世界中的很多过程都具有多条线索同时动作的特性。
Java语言的一大特性就是内置对多线程的支持。
多线程是指同时存在几个执行体,按几条不同的执行线索共同工作的情况,它使得编程人员可以很方便地开发出具有多线程功能、能同时处理多个任务的功能强大的应用程序。
一些同时运行的线程需要共享数据,因此每个线程就必须要考虑其它与它一起共享数据的线程的状态与行为,这就是线程安全的问题。
为了对Java多线程与线程安全机制进行研究与实践,特此设计一个基于Http 协议的支持多线程断点续传的下载程序。
此下载程序由下载任务模块、设置模块以及系统帮助模块组成。
通过Apache Jakarta Commons下的子项目HttpClient包对Http协议进行支持,从而下载服务器端的资源。
程序提供多线程断点续传功能,在完成下载过程中使用多线程技术可以较大幅度地提高下载的速度。
关键词:多线程;线程安全;断点续传目录论文总页数:25页1引言............................................................................................................. 错误!未定义书签。
1.1 课题的研究背景与意义...................................................................... 错误!未定义书签。
1.1.1 课题的研究背景......................................................................... 错误!未定义书签。
1.1.2课题的研究意义......................................................................... 错误!未定义书签。
题目:Java+FFmpeg断点续传原理一、介绍Java和FFmpeg作为两个独立的工具,它们各自都有着强大的功能,而将它们结合起来,可以实现一些更加复杂而有用的功能。
其中,断点续传就是其中之一。
在本篇文章中,我们将探讨Java和FFmpeg如何结合实现断点续传的原理。
二、Java实现断点续传在Java中要实现断点续传,需要考虑以下几个方面:1. 文件下载与断点记录我们需要利用Java的文件下载功能将文件下载到本地。
在下载的过程中,需要实时记录已下载的文件大小,并将其保存在本地。
这样,在下次继续下载时,我们可以读取已下载的文件大小,从该位置继续下载。
2. 文件分片对于大文件,为了更好地实现断点续传,通常会将文件分成若干个小的片段进行下载。
这样可以避免出现意外中断时需要重新下载整个文件的情况。
在Java中,我们可以通过文件分片的方式来实现断点续传。
3. 断点续传的实现当下载过程中出现中断时,我们需要能够从上次中断的位置开始继续下载。
在Java中,可以通过读取保存的已下载文件大小,选取合适的下载策略来实现断点续传。
三、FFmpeg的信息和断点续传在FFmpeg中,主要涉及到的是视频的信息和下载。
通常情况下,我们可以通过FFmpeg来下载视频及音频文件,实现视频的处理和转码等功能。
但对于断点续传,FFmpeg也可以发挥出其强大的功能。
1. FFmpeg的下载功能FFmpeg提供了丰富的下载功能,可以实现从网络上下载视频及音频文件。
在下载时,FFmpeg也支持对下载过程中的断点续传,可以通过指定参数来实现。
2. 断点续传的实现在FFmpeg中,断点续传的实现与Java类似,都需要记录已下载的文件大小,并在下次继续下载时从该位置开始。
不过在FFmpeg中,我们可以通过命令行参数来指定下载的起始位置,从而实现断点续传。
四、结合Java和FFmpeg的断点续传当我们将Java和FFmpeg结合起来时,就可以实现更加强大和灵活的断点续传功能了。
断点续传原理与实现嘿,朋友们!今天咱来聊聊断点续传原理与实现,这可真是个有意思的玩意儿呢!你想想看啊,咱平时下载个大文件,要是网络突然断了,那得多闹心啊!难道就得从头再来?那可太浪费时间和精力啦!这时候断点续传就像个超级英雄一样出现啦!它就好比是你在跑马拉松,中间累了歇会儿,等会儿还能接着从你停下的地方继续跑,而不是回到起点重新开始。
多棒啊!那断点续传到底是怎么实现的呢?其实啊,就像是给文件下载的过程做了个标记。
比如说,文件一共有 100 段,你已经下载到第 50 段的时候断网了,那等网络恢复后,它能知道从第 51 段开始接着下。
这就好像是在走迷宫,你已经走过一部分了,标记好了路线,下次再进去就可以直接从上次的地方继续走,不用再傻乎乎地从头开始摸索啦!实现断点续传,得有一些关键的步骤和技术。
首先呢,得有个记录点,就像你在笔记本上做个记号一样,记住已经下载的部分。
然后呢,还得有个检测机制,能随时发现网络是不是断了,或者什么时候恢复了。
你说这神奇不神奇?它怎么就能这么聪明地知道该从哪里接着来呢?这背后可都是程序员们的智慧结晶呀!咱再举个例子,你去图书馆看书,一本书好几百页呢,你看了一半要回家了,难道下次来还得从头开始翻?那多麻烦呀!这时候要是有个标记,下次直接翻到你上次看到的地方,那得多爽!断点续传不就是这么个道理嘛!在实际应用中,断点续传可太重要啦!无论是下载软件、游戏,还是大的文件资料,都离不开它。
不然,每次断网都得重新开始,那得把人逼疯咯!而且啊,断点续传还让下载变得更高效、更可靠。
就像是给下载过程上了一道保险,让你不用担心意外情况打断你的进度。
朋友们,想想看,如果没有断点续传,那我们得浪费多少时间和精力在重复下载上啊!它真的是给我们的网络生活带来了极大的便利呢!所以说呀,断点续传原理与实现可真是个了不起的东西!它让我们的网络体验更加顺畅、愉快。
咱可得好好感谢那些发明和完善它的人呢!不是吗?原创不易,请尊重原创,谢谢!。
断点续传原理及运⽤⼀,断点续传(断点续传其实就是把⽂件分割的过程,⼀段⼀段的传。
)断点续传需要和后端进⾏配合进⾏处理,这⾥我提供⼀下后端那边提供的接⼝1,后端接⼝提供其实原理也很简单说⽩了,就是我们把本地的⼤型⽂件或者视频使⽤slice进⾏分割,然后传给后台,同时需要提供给后台当前分割的索引和⼀共要分成多少份。
(废话不多说,上代码)2,前端代码部署点击上传按钮⽅法filesVide() {// 视频上传this.datafile=this.$refs.file.files[0];// 上传的⽂件的⼤⼩this.size=(this.datafile.size/1024/1024).toFixed(1);this.filesize = this.datafile.size;this.fileName = ;// 判断后缀var index=stIndexOf('.');var type1=.slice(index+1);// 进⾏判断是不是mp4格式,如果不是进⾏提⽰处理if(type1!=='mp4'||this.filesize>1024*1024*500){// 提⽰处理this.MP4sp=true;this.clearTimers();this.$refs.file.value='';return;}// 以下为⼀些提⽰处理(可以先不⽤考虑)this.cut=true;this.videcut=false;this.cutvide=false;this.index=0;this.baifenbi=0;this.suo=true;this.start=0;this.end=0;// ⼀共多少个⽚段戳(bytesPerPiece=1024*1024表⽰每次上传的⼤⼩为1m)this.total = Math.ceil(this.filesize / this.bytesPerPiece);// 时间戳this.timestamp=new Date().getTime();// 进⾏上传的代码⽚段this.pianduanfiles();},这个地⽅是点击上传时需要进⾏的处理。
由于业务需要,手机需要采用http方式传输文件到后台WEB服务器,1、2百K的小文件不会有太大问题,几M甚至几百M的文件就很容易传输失败。
所以考虑实现HTTP文件断点续传功能,基本流程如下:1.客户端计算本地要上传的文件的hashcode2.根据指定的块大小和文件大小计算最终的块数3.发送文件信息到服务器包括要上传的文件名、大小、类型、块数、Hashcode4.服务器根据hashcode查询服务器上是否已经存在对应的文件,以及文件的上传状态(上传是否完成、是否组装完成、已经上传了哪些块)5.6.已经上传完成的读取文件URL地址返回给客户端7.8.未上传完成的返回已经上传的块编号9.客户端根据返回值判断,如果未上传完成则从本地文件中读取未上传完成的块内容10.使用HTTP方式上传到服务器11.记录已经上传完成的块到数据库12.检查整个文件是否已经上传完成13.未完成则返回已经上传的块编号到客户端让它继续上传14.上传完成则进行块文件合并过程,将其合并成目标文件15.合并完成后返回目标文件的URL地址首先是数据库表格:createtable tb_fileupload(fseq intprimarykey auto_increment, #自增序列fusername varchar(50), #上传者fhashcode varchar(100), #hash码fsize int, #文件大小fblocks int, #块数ftype varchar(50), #文件类型fready varchar(1024), #已上传完成的块编号finerpath varchar(200), #内部存储路径fouterpath varchar(200), #外部存储路径fisfinished intdefault0, #要否上传完成ftime datetime #创建时间)接下来是客户端代码:import java.io.FileInputStream;publicclass Auth{publicstaticbyte[] create(String filename) throws Excepiton{ InputStreamfis = new FileInputStream(filename);byte[] buf= newbyte[1024];MessageDigest com=MessageDigest.getInstance("MD5");int num;do{num=fis.read(buf);if(num>0){com.update(buf,0,num);}}while(num!=-1)fis.close();return com.digest();}publicstatic String getMD5(String filename) throw Exception {byte[] b =create(filename);String result="";for(int i=0;i<b.length;i++){result+=Integer.toString( (b[i]&0xff)+0x100,16).substring(1);}return result;}}服务器端代码包括以下几部分:1.新增要上传的文件信息。
java的http断点续传原理(二)//获得文件长度public long getFileSize(){int nFileLength = -1;try{URL url = new URL(siteInfoBean.getSSiteURL());HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection (); httpConnection.setRequestProperty("User-Agent","NetFox");int responseCode=httpConnection.getResponseCode();if(responseCode>=400){processErrorCode(responseCode);return -2; //-2 represent access is error}String sHeader;for(int i=1;;i++){//DataInputStream in = new DataInputStream(httpConnection.getInputStream ()); //Utility.log(in.readLine());sHeader=httpConnection.getHeaderFieldKey(i);if(sHeader!=null){if(sHeader.equals("Content-Length")){nFileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader)); break;}}elsebreak;}}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=0;i< p>{// 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=0;i< p>{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=0;i< p>fileSplitterFetch[i].splitterStop();}}/***FileSplitterFetch.java*/package NetFox;import java.io.*;import .*;public class FileSplitterFetch extends Thread {String sURL; //File URLlong nStartPos; //File Snippet Start Positionlong nEndPos; //File Snippet End Positionint nThreadID; //Thread's IDboolean bDownOver = false; //Downing is overboolean bStop = false; //Stop identicalFileAccessI fileAccessI = null; //File Access interfacepublic FileSplitterFetch(String sURL,String sName,long nStart,long nEnd,int id) throws IOException{this.sURL = sURL;this.nStartPos = nStart;this.nEndPos = nEnd;nThreadID = id;fileAccessI = new FileAccessI(sName,nStartPos);}public void run(){while(nStartPos < nEndPos && !bStop){try{URL url = new URL(sURL);HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection ();httpConnection.setRequestProperty("User-Agent","NetFox");String sProperty = "bytes="+nStartPos+"-";httpConnection.setRequestProperty("RANGE",sProperty);Utility.log(sProperty);InputStream input = httpConnection.getInputStream();//logResponseHead(httpConnection);byte[] b = new byte[1024];int nRead;while((nRead=input.read(b,0,1024)) > 0 && nStartPos < nEndPos && !bStop) {nStartPos += fileAccessI.write(b,0,nRead);//if(nThreadID == 1)// Utility.log("nStartPos = " + nStartPos + ", nEndPos = " + nEndPos); }Utility.log("Thread " + nThreadID + " is over!");bDownOver = true;//nPos = fileAccessI.write (b,0,nRead);}catch(Exception e){e.printStackTrace ();}}}//打印回应的头信息public void logResponseHead(HttpURLConnection con){for(int i=1;;i++){String header=con.getHeaderFieldKey(i);if(header!=null)//responseHeaders.put(header,httpConnection.getHeaderField(header)); Utility.log(header+" : "+con.getHeaderField(header));elsebreak;}}public void splitterStop(){bStop = true;}}/***FileAccess.java*/package NetFox;import java.io.*;public class FileAccessI implements Serializable{ RandomAccessFile oSavedFile;long nPos;public FileAccessI() throws IOException{this("",0);}public FileAccessI(String sName,long nPos) throws IOException {oSavedFile = new RandomAccessFile(sName,"rw");this.nPos = nPos;oSavedFile.seek(nPos);}public synchronized int write(byte[] b,int nStart,int nLen) {int n = -1;try{oSavedFile.write(b,nStart,nLen);n = nLen;}catch(IOException e){e.printStackTrace ();}return n;}}/***SiteInfoBean.java*/package NetFox;public class SiteInfoBean {private String sSiteURL; //Site's URLprivate String sFilePath; //Saved File's Pathprivate String sFileName; //Saved File's Nameprivate int nSplitter; //Count of Splited Downloading Filepublic SiteInfoBean(){//default value of nSplitter is 5this("","","",5);}public SiteInfoBean(String sURL,String sPath,String sName,int nSpiltter) {sSiteURL= sURL;sFilePath = sPath;sFileName = sName;this.nSplitter = nSpiltter;}public String getSSiteURL(){return sSiteURL;}public void setSSiteURL(String value) {sSiteURL = value;}public String getSFilePath(){return sFilePath;}public void setSFilePath(String value) {sFilePath = value;}public String getSFileName(){return sFileName;}public void setSFileName(String value) {sFileName = value;}public int getNSplitter(){return nSplitter;}public void setNSplitter(int nCount) {nSplitter = nCount;}}/***Utility.java*/package NetFox;public class Utility {public Utility(){}public static void sleep(int nSecond) {try{Thread.sleep(nSecond);}catch(Exception e){e.printStackTrace ();}}public static void log(String sMsg){System.err.println(sMsg);}public static void log(int sMsg){System.err.println(sMsg);}}/***TestMethod.java*/package NetFox;public class TestMethod {public TestMethod(){ ///xx/weblogic60b2_win.exetry{SiteInfoBean bean = newSiteInfoBean("http://localhost/xx/weblogic60b2_win.exe","L:\\temp","weblogic60b2_w in.exe",5);//SiteInfoBean bean = newSiteInfoBean("http://localhost:8080/down.zip","L:\\temp","weblogic60b2_win.exe",5) ;SiteFileFetch fileFetch = new SiteFileFetch(bean);fileFetch.start();}catch(Exception e){e.printStackTrace ();}}public static void main(String[] args){new TestMethod();。