内容简介:一步一步带你起飞 ... ...计算机是以字节(byte|B)为单位计算存储空间大小,如:1个数字和1个字母占用1个字节大小,而1个汉字是2个字节大小,常用单位有:KB\MB\GB\TB,再往上还有PB\EB\ZB\YB\BB。对换关系,如下:
一步一步带你起飞 ... ...
一、文件存储单位“字节”概念
1.1 存储单位
计算机是以字节(byte|B)为单位计算存储空间大小,如:1个数字和1个字母占用1个字节大小,而1个汉字是2个字节大小,常用单位有:KB\MB\GB\TB,再往上还有PB\EB\ZB\YB\BB。
对换关系,如下:
1024B = 1KB 1024KB = 1MB 1024MB = 1GB 1024GB = 1TB 1024TB = 1PB ...
1.2 文件举例
一个txt格式的文件:001.txt
- 内容:“abcd”,大小:“4字节”
- 内容:“abcd123”,大小:“7字节”
- 内容:“abcd123我”,大小:“9字节”
二、断点续传原理
文件在网络传输过程中时常会面对网络中断的情况,对于比较大的文件(花了30分钟上传了1G,还剩下2G没有完成)突然网断了,若重头开始上传的话前面花费30分钟时间上次的1G就完全浪费了(浪费时间、浪费流量),所以需要有一种机制可以从中断地方继续开始上传,这就是"断点续传"的概念。
2.1 断点存储
一般文件远程传输时不是直接存储为原文件格式,会存储为一个临时的格式,比如".temp",当文件传输完成后再修改为原文件格式名,比较常用的做法是之间在原文件名的后缀后面添加“.temp”后缀,如:“001.txt.temp”
对于只是续传来说临时文件的大小就可以认为是当前的断点,因为是往后追加方式存储,也有很多的下载上传工具(QQ旋风,迅雷,FTP客户端等)是支持多线程并发传输的,这个时候需要分配并记录多个断点。
比如:一个1024byte大小文件在远程接收时,以200byte为一个缓存块进行传输文件,也就是分隔成“0-200,201-401,402-602,603-803,804-1004,1005-1024”并行传输,传输效率提升非常可观。
2.2 文件续传读取
比如已经存储到508byte大小,那么需要从509byte开始上传,对于发送客户端需要从指定位置开始读取指定长度的文件字节码,发送给接收端。可以通过具体SDK包方法移动到文件某个字节位置开始读取指定大小,目前的开发语言库基本都支持此类的开发包。
2.3 文件续传存储
文件在网络中传输是通过字节码方式作为一个文件流。接收端收到的文件字节码流需要带有标志信息,如“337byte-797byte”,这样就可以把该字节流存储到临时文件中该指定位置,多次续传最终拼接成一个完整的文件。
2.4 文件校验-判断是否变化
在实际的上传下载操作中,存在文件发送过程中被变更的场景,所以在续传时需要明确知道文件是否变动,否则存储就会出现数据错误。没有变动继续续传,有变动重新开始传输。
本质是在文件传输端生成一个 标志 ,发送给接收的端每次去比对是否一直一样。
三、http1.1协议支持策略
3.1 OSI模型定义
http1.1协议定义了断点续传文件内容的http请求头参数:Range\Content-Range。Range参数是本地发往服务器的http头参数。Content-Range是远程服务器发往本地http头参数。
3.2 Range\Cotent-Range
range: (unit=first byte pos)-[last byte pos]
: 指定第一个字节位置和最后一个字节位置。
例子说明:
range: bytes=0-1300
表示第0-1300字节范围的内容发往远程服务器。
range: bytes=1301-23041
表示第1201-23041字节范围的内容发往远程服务器。
Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]
例子说明
content-Range: bytes 0-797/1024000
表示0-797字节范围内容从服务器响应到客户端,1024000是文件总大小。
完成http响应后,http状态码返回:206 表示使用断掉续传方式,而一般200表示不使用断掉续传方式。
3.3 Last-Modified\If-Modified-Since
利用HTTP协议头Last-Modified\If-Modified-Since参数存储文件最后修改日期,每次通信文件要判断与上一次文件最后修改日期是否相同,如果不同就从0开始重新接收文件,相同则继续。Last-Modified 是由服务器往客户端发送的 HTTP 头,而If-Modified-Since 则是由客户端往服务器发送的头。
例如:
Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT
服务器端返回客户端HTTP头信息。
If-Modified-Since: Fri, 22 Feb 2013 03:45:02 GMT
客户端通过 If-Modified-Since HTTP头将上一次服务器端发过来的 Last-Modified 时间戳发送回服务器端进行比较验证。
3.4 Etag\If-Range
Etage也是一种校验的策略,服务器发送给客户端的HTTP头带上Etage参数,客户端发送给服务器通过If-Range把上一次的Etage参数返回给服务器端验证,如果不一样就返回完整从0字节开始的内容,206状态码;若果一样就继续返回要求的自己内容,200状态码。
Etage机制是弥补一些Last-Modified无法支持的场景,如服务无法识别文件最后修改时间,又或者在秒以下的时间内进行修改N次。HTTP/1.1标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag必须用""括起来,所以Etage是由服务器端决定按什么策略生产,不同公司不同见解了。
除了If-Range外还有If-Match\If-None-Match两种参数,用法同If-Range一样,如下:
服务器端发送 | 客户端发送 |
---|---|
Etage: "112233" | If-Range: "112233" |
If-Match: "112233" | |
If-None-Match: "112233" |
3.4 http断掉续传测试验证
举例: --Range 0-1000
$ curl.exe -i --Range 0-1000 http://www.baidu.com/img/bdlogo.gif % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1001 100 1001 0 0 21760 0 --:--:-- --:--:-- --:--:-- 21760HTTP/1.1 206 Partial Content Accept-Ranges: bytes Cache-Control: max-age=315360000 Connection: Keep-Alive Content-Length: 1001 Content-Range: bytes 0-1000/1575 Content-Type: image/gif Date: Fri, 07 Jun 2019 06:50:06 GMT Etag: "627-4d648041f6b80" Expires: Mon, 04 Jun 2029 06:50:06 GMT Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT P3p: CP=" OTI DSP COR IVA OUR IND COM " Server: Apache Set-Cookie: BAIDUID=46BF24BA4F3649CE9214E2DA266439B1:FG=1; expires=Sat, 06-Jun-20 06:50:06 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1 GIF89a▒▒`g▒▒1.▒▒▒▒▒▒▒▒jg▒▒▒▒▒▒▒▒▒▒▒▒▒4<▒EL▒)2▒▒▒▒▒!▒,▒▒▒▒I▒▒8▒ͻ▒`(▒di▒h▒▒l▒p,▒tm▒x▒▒|▒▒▒▒pH,▒Ȥr▒l:▒ШtJ▒Z▒جv▒▒z▒▒xL.▒▒▒z▒n▒▒▒|N▒▒▒▒▒~▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒▒ ▒▒▒▒ ▒▒}▒▒ ▒z▒▒▒▒▒▒ã ▒ ▒▒▒▒▒o▒▒▒▒▒▒▒m آ▒▒s▒ ▒▒▒▒▒▒▒▒▒▒@▒▒h▒▒▒▒w▒&$#A*N▒▒▒5!Z3▒▒▒$▒g▒▒a▒H▒ IF#▒▒▒H▒▒▒▒▒▒▒a̙6▒▒▒▒▒xT%ƠV▒+xB▒P▒P▒x▒▒▒*▒▒Sp[Xb▒0▒`▒<▒b-ѴP▒▒BK▒▒} ▒^▒▒ ▒▒▒.P▒ ] 1▒u▒▒▒.l ▒QX▒`▒▒w▒▒@▒▒▒▒▒9▒▒Ӣ(0▒E▒▒.Lp▒d▒▒lz4▒Ҩ▒▒&▒▒ih▒Нݐs[▒N}▒▒▒[▒▒u▒'▒▒▒▒▒▒b▒▒~▒C▒ݻ[▒▒];▒▒CX!t▒▒h▒▒▒▒ئ :▒▒7▒| _▒=▒`▒▒1▒▒h▒(▒X"xm▒_|▒▒▒( @▒▒7~p1▒▒nV▒*▒▒!▒E▒g▒▒▒M8A▒,Bx ▒;8e▒▒]y%▒▒▒▒":)▒u▒▒▒▒I▒f▒Q▒K ▒▒▒▒ ▒▒▒nn▒i ▒▒jNVȁ▒u▒▒▒}▒▒▒▒:▒▒vSr▒▒▒p▒▒f▒;[▒ً▒"V:i▒▒Z h▒ ▒ok*h_▒Y▒=▒▒▒(K▒&▒ Tg▒ ▒▒ˣ▒ ▒▒▒*hL2▒▒▒t▒Z▒V[▒▒z֚▒w▒▒v▒l▒▒▒▒▒3J▒▒6▒▒▒▒▒▒▒Kh▒▒^▒n[A▒&▒8\▒▒▒u▒d4@▒▒މ▒▒▒▒me*[▒▒(▒▒▒▒/}jn`▒▒▒jLI▒`▒▒▒▒·▒▒▒▒▒Ɨ▒B▒v▒▒▒"? ▒<T
说明:
获取0-1000字节的内容,服务器返回状态码206,标识成功。
Etag: "627-4d648041f6b80"
Content-Length: 1001
Content-Range: bytes 0-1000/1575
举例: --Range 1001-1575 --header 'If-Range: "627-4d648041f6b80"'
$ curl.exe -i --Range 1001-1575 --header 'If-Range: "627-4d648041f6b80"' http://www.baidu.com/img/bdlogo.gif % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 574 100 574 0 0 12478 0 --:--:-- --:--:-- --:--:-- 12478HTTP/1.1 206 Partial Content Accept-Ranges: bytes Cache-Control: max-age=315360000 Connection: Keep-Alive Content-Length: 574 Content-Range: bytes 1001-1574/1575 Content-Type: image/gif Date: Fri, 07 Jun 2019 06:54:44 GMT Etag: "627-4d648041f6b80" Expires: Mon, 04 Jun 2029 06:54:44 GMT Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT P3p: CP=" OTI DSP COR IVA OUR IND COM " Server: Apache Set-Cookie: BAIDUID=0E38B0989374B9F142B24462CD98ADA4:FG=1; expires=Sat, 06-Jun-20 06:54:44 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1 ▒▒01c<▒▒mV▒▒[▒▒u▒▒▒-C▒▒▒▒s]▒▒M▒\▒u|▒▒w▒▒▒▒▒▒x▒T▒K]▒ ZK▒?▒▒g▒▒▒৳▒▒[M▒ZH_p▒▒c▒▒F▒y▒7▒▒▒I@▒▒▒~h▒▒▒▒]=▒▒▒&▒▒cU▒=▒▒▒GJ▒}▒k▒i▒W=w▒΅-▒+▒H`▒H▒▒()' (▒j▒▒▒i▒▒3 &▒9▒8▒3Ą▒▒▒uJ▒&6▒J4:c^▒^tb▒6ܚ▒▒▒ ▒▒j▒▒.▒9O▒▒ac▒ц▒▒3=▒Ս▒h̞▒G▒▒4+da▒▒▒▒▒J▒J▒J֘▒▒:oD ▒▒▒D ( ▒ ▒▒▒UƼt▒[▒▒▒▒j▒▒?NiBc-▒▒^▒▒▒▒SK▒▒s▒ ▒0▒I▒b▒▒L▒2▒▒▒f:▒Ќ▒4▒I▒jZ▒▒̦6▒▒▒nz▒▒ ▒8▒I▒r▒▒▒L▒:▒▒▒v▒▒▒▒▒<▒I▒z▒ ;
说明:
获取1001-1575字节码内容,返回码206标识成功。两次请求的Content-Length字段值相加(1001+574=1575)正好等于总长度。
Content-Range: bytes 1001-1574/1575
Content-Length: 574
Etag: "627-4d648041f6b80"
举例Etag校验失败: --Range 1001-1575 --header 'If-Range: "627-4d648041f6b81"'
$ curl.exe -i --Range 1001-1575 --header 'If-Range: "627-4d648041f6b81"' http://www.baidu.com/img/bdlogo.gif % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1575 100 1575 0 0 25403 0 --:--:-- --:--:-- --:--:-- 25403HTTP/1.1 200 OK Accept-Ranges: bytes Cache-Control: max-age=315360000 Connection: Keep-Alive Content-Length: 1575 Content-Type: image/gif Date: Fri, 07 Jun 2019 07:07:53 GMT Etag: "627-4d648041f6b80" Expires: Mon, 04 Jun 2029 07:07:53 GMT Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT P3p: CP=" OTI DSP COR IVA OUR IND COM " Server: Apache Set-Cookie: BAIDUID=77C9D6AD24F8A5F39F1B35D7D351D05C:FG=1; expires=Sat, 06-Jun-20 07:07:53 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1 GIF89a▒▒`g▒▒1.▒▒▒▒▒▒▒▒jg▒▒▒▒▒▒▒▒▒▒▒▒▒4<▒EL▒)2▒▒▒▒▒!▒,▒▒▒▒I▒▒8▒ͻ▒`(▒di▒h▒▒l▒p,▒tm▒x▒▒|▒▒▒▒pH,▒Ȥr▒l:▒ШtJ▒Z▒جv▒▒z▒▒xL.▒▒▒z▒n▒▒▒|N▒▒▒▒▒~▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒▒ ▒▒▒▒ ▒▒}▒▒ ▒z▒▒▒▒▒▒ã ▒ ▒▒▒▒▒o▒▒▒▒▒▒▒m آ▒▒s▒ ▒▒▒▒▒▒▒▒▒▒@▒▒h▒▒▒▒w▒&$#A*N▒▒▒5!Z3▒▒▒$▒g▒▒a▒H▒ IF#▒▒▒H▒▒▒▒▒▒▒a̙6▒▒▒▒▒xT%ƠV▒+xB▒P▒P▒x▒▒▒*▒▒Sp[Xb▒0▒`▒<▒b-ѴP▒▒BK▒▒} ▒^▒▒ ▒▒▒.P▒ ] 1▒u▒▒▒.l ▒QX▒`▒▒w▒▒@▒▒▒▒▒9▒▒Ӣ(0▒E▒▒.Lp▒d▒▒lz4▒Ҩ▒▒&▒▒ih▒Нݐs[▒N}▒▒▒[▒▒u▒'▒▒▒▒▒▒b▒▒~▒C▒ݻ[▒▒];▒▒CX!t▒▒h▒▒▒▒ئ :▒▒7▒| _▒=▒`▒▒1▒▒h▒(▒X"xm▒_|▒▒▒( @▒▒7~p1▒▒nV▒*▒▒!▒E▒g▒▒▒M8A▒,Bx ▒;8e▒▒]y%▒▒▒▒":)▒u▒▒▒▒I▒f▒Q▒K ▒▒▒▒ ▒▒▒nn▒i ▒▒jNVȁ▒u▒▒▒}▒▒▒▒:▒▒vSr▒▒▒p▒▒f▒;[▒ً▒"V:i▒▒Z h▒ ▒ok*h_▒Y▒=▒▒▒(K▒&▒ Tg▒ ▒▒ˣȆ▒01c<▒▒mV▒▒[▒▒u▒▒▒-C▒▒▒▒s]▒▒M▒\▒u|▒▒w▒▒▒▒▒▒x▒T▒K]▒▒▒Kh▒▒^▒n[A▒&▒8\▒▒▒u▒d4@▒▒މ▒▒▒▒me*[▒▒(▒▒▒▒/}jn`▒▒▒jLI▒`▒▒▒▒·▒▒▒▒▒Ɨ▒B▒v▒▒▒"? ▒<T ZK▒?▒▒g▒▒▒৳▒▒[M▒ZH_p▒▒c▒▒F▒y▒7▒▒▒I@▒▒▒~h▒▒▒▒]=▒▒▒&▒▒cU▒=▒▒▒GJ▒}▒k▒i▒W=w▒΅-▒+▒H`▒H▒▒()'▒ (▒j▒▒▒i▒▒3 &▒9▒8▒3Ą▒▒▒uJ▒&6▒J4:c^▒^tb▒6ܚ▒▒▒ ▒▒j▒▒.▒9O▒▒ac▒ц▒▒3=▒Ս▒h̞▒G▒▒4+da▒▒▒▒▒J▒J▒J֘▒▒:oD ▒▒▒D ( ▒ ▒▒▒UƼt▒[▒▒▒▒j▒▒?NiBc-▒▒^▒▒▒▒SK▒▒s▒ ▒0▒I▒b▒▒L▒2▒▒▒f:▒Ќ▒4▒I▒jZ▒▒̦6▒▒▒nz▒▒ ▒8▒I▒r▒▒▒L▒:▒▒▒v▒▒▒▒▒<▒I▒z▒ ;
说明:
通过If-Range与Etag比较发现值不同,此时没有Content-Range头参数信息,服务器则把完整的文件内容全部传给客户端。
If-Range: "627-4d648041f6b81"
Etag: "627-4d648041f6b80"
比较着看你会发现同一般非断点续传的HTTP请求返回一样,如下:
$ curl.exe -i http://www.baidu.com/img/bdlogo.gif % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1575 100 1575 0 0 34239 0 --:--:-- --:--:-- --:--:-- 34239HTTP/1.1 200 OK Accept-Ranges: bytes Cache-Control: max-age=315360000 Connection: Keep-Alive Content-Length: 1575 Content-Type: image/gif Date: Fri, 07 Jun 2019 07:11:20 GMT Etag: "627-4d648041f6b80" Expires: Mon, 04 Jun 2029 07:11:20 GMT Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT P3p: CP=" OTI DSP COR IVA OUR IND COM " Server: Apache Set-Cookie: BAIDUID=1F8BCA97A9EB1C3123305CC96E3AFD12:FG=1; expires=Sat, 06-Jun-20 07:11:20 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1 GIF89a▒▒`g▒▒1.▒▒▒▒▒▒▒▒jg▒▒▒▒▒▒▒▒▒▒▒▒▒4<▒EL▒)2▒▒▒▒▒!▒,▒▒▒▒I▒▒8▒ͻ▒`(▒di▒h▒▒l▒p,▒tm▒x▒▒|▒▒▒▒pH,▒Ȥr▒l:▒ШtJ▒Z▒جv▒▒z▒▒xL.▒▒▒z▒n▒▒▒|N▒▒▒▒▒~▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒▒ ▒▒▒▒ ▒▒}▒▒ ▒z▒▒▒▒▒▒ã ▒ ▒▒▒▒▒o▒▒▒▒▒▒▒m آ▒▒s▒ ▒▒▒▒▒▒▒▒▒▒@▒▒h▒▒▒▒w▒&$#A*N▒▒▒5!Z3▒▒▒$▒g▒▒a▒H▒ IF#▒▒▒H▒▒▒▒▒▒▒a̙6▒▒▒▒▒xT%ƠV▒+xB▒P▒P▒x▒▒▒*▒▒Sp[Xb▒0▒`▒<▒b-ѴP▒▒BK▒▒} ▒^▒▒ ▒▒▒.P▒ ] 1▒u▒▒▒.l ▒QX▒`▒▒w▒▒@▒▒▒▒▒9▒▒Ӣ(0▒E▒▒.Lp▒d▒▒lz4▒Ҩ▒▒&▒▒ih▒Нݐs[▒N}▒▒▒[▒▒u▒'▒▒▒▒▒▒b▒▒~▒C▒ݻ[▒▒];▒▒CX!t▒▒h▒▒▒▒ئ :▒▒7▒| _▒=▒`▒▒1▒▒h▒(▒X"xm▒_|▒▒▒( @▒▒7~p1▒▒nV▒*▒▒!▒E▒g▒▒▒M8A▒,Bx ▒;8e▒▒]y%▒▒▒▒":)▒u▒▒▒▒I▒f▒Q▒K ▒▒▒▒ ▒▒▒nn▒i ▒▒jNVȁ▒u▒▒▒}▒▒▒▒:▒▒vSr▒▒▒p▒▒f▒;[▒ً▒"V:i▒▒Z h▒ ▒ok*h_▒Y▒=▒▒▒(K▒&▒ Tg▒ ▒▒ˣȆ▒01c<▒▒mV▒▒[▒▒u▒▒▒-C▒▒▒▒s]▒▒M▒\▒u|▒▒w▒▒▒▒▒▒x▒T▒K]▒▒▒Kh▒▒^▒n[A▒&▒8\▒▒▒u▒d4@▒▒މ▒▒▒▒me*[▒▒(▒▒▒▒/}jn`▒▒▒jLI▒`▒▒▒▒·▒▒▒▒▒Ɨ▒B▒v▒▒▒"? ▒<T ZK▒?▒▒g▒▒▒৳▒▒[M▒ZH_p▒▒c▒▒F▒y▒7▒▒▒I@▒▒▒~h▒▒▒▒]=▒▒▒&▒▒cU▒=▒▒▒GJ▒}▒k▒i▒W=w▒΅-▒+▒H`▒H▒▒()'▒ (▒j▒▒▒i▒▒3 &▒9▒8▒3Ą▒▒▒uJ▒&6▒J4:c^▒^tb▒6ܚ▒▒▒ ▒▒j▒▒.▒9O▒▒ac▒ц▒▒3=▒Ս▒h̞▒G▒▒4+da▒▒▒▒▒J▒J▒J֘▒▒:oD ▒▒▒D ( ▒ ▒▒▒UƼt▒[▒▒▒▒j▒▒?NiBc-▒▒^▒▒▒▒SK▒▒s▒ ▒0▒I▒b▒▒L▒2▒▒▒f:▒Ќ▒4▒I▒jZ▒▒̦6▒▒▒nz▒▒ ▒8▒I▒r▒▒▒L▒:▒▒▒v▒▒▒▒▒<▒I▒z▒ ;
If-Match举例(If-None-Match完全一样),如下:
$ curl.exe -i --Range 1001-1575 --header 'If-Match: "627-4d648041f6b80"' http://www.baidu.com/img/bdlogo.gif % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 574 100 574 0 0 12212 0 --:--:-- --:--:-- --:--:-- 12212HTTP/1.1 206 Partial Content Accept-Ranges: bytes Cache-Control: max-age=315360000 Connection: Keep-Alive Content-Length: 574 Content-Range: bytes 1001-1574/1575 Content-Type: image/gif Date: Fri, 07 Jun 2019 10:21:48 GMT Etag: "627-4d648041f6b80" Expires: Mon, 04 Jun 2029 10:21:48 GMT Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT P3p: CP=" OTI DSP COR IVA OUR IND COM " Server: Apache Set-Cookie: BAIDUID=A87AAF66C9055950B0240738025FD7CF:FG=1; expires=Sat, 06-Jun-20 10:21:48 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1 ▒▒01c<▒▒mV▒▒[▒▒u▒▒▒-C▒▒▒▒s]▒▒M▒\▒u|▒▒w▒▒▒▒▒▒x▒T▒K]▒ ZK▒?▒▒g▒▒▒৳▒▒[M▒ZH_p▒▒c▒▒F▒y▒7▒▒▒I@▒▒▒~h▒▒▒▒]=▒▒▒&▒▒cU▒=▒▒▒GJ▒}▒k▒i▒W=w▒΅-▒+▒H`▒H▒▒()' (▒j▒▒▒i▒▒3 &▒9▒8▒3Ą▒▒▒uJ▒&6▒J4:c^▒^tb▒6ܚ▒▒▒ ▒▒j▒▒.▒9O▒▒ac▒ц▒▒3=▒Ս▒h̞▒G▒▒4+da▒▒▒▒▒J▒J▒J֘▒▒:oD ▒▒▒D ( ▒ ▒▒▒UƼt▒[▒▒▒▒j▒▒?NiBc-▒▒^▒▒▒▒SK▒▒s▒ ▒0▒I▒b▒▒L▒2▒▒▒f:▒Ќ▒4▒I▒jZ▒▒̦6▒▒▒nz▒▒ ▒8▒I▒r▒▒▒L▒:▒▒▒v▒▒▒▒▒<▒I▒z▒ ;
四、 java 文件读写
常用的字节或字符流操作文件默认都是从文件开始位置写入(从0开始),但是我们需要的是从指定位置开始写入并控制写入多少。
4.1 例子
//File content: “1234abc我” File file = new File("F:\\tmp\\001.txt"); System.out.println(file.length()); //输出:9 String insert = "1tt1"; byte[] bytes = insert.getBytes(); long currentLength = file.length(); System.out.println(bytes.length); //输出:4 RandomAccessFile raf = new RandomAccessFile(file,"rw"); raf.seek(currentLength+5);//写入位置指定到第15字节处开始 raf.write(bytes,0,bytes.length); System.out.println(file.length()); //输出:18 //文件内容:“1234abc我 1tt1” insert+=","; bytes = insert.getBytes(); raf.seek(currentLength);//写入位置指定到第10字节处开始 raf.write(bytes,0,bytes.length); System.out.println(file.length()); //输出:18 //文件内容:“1234abc我1tt1,1tt1”
4.2 说明
通过 Java RandomAccessFile 类的 .seek(..) 方法可以控制文件写入位置。例子中第二次写入内容“1tt1,”是从第10个字节处写入内容。
4.3 Java .seek(..) 方法源码
注意看方法的注释:在写入内容前改变file-pointer offset不会影响文件的大小。
/** * Sets the file-pointer offset, measured from the beginning of this * file, at which the next read or write occurs. The offset may be * set beyond the end of the file. Setting the offset beyond the end * of the file does not change the file length. The file length will * change only by writing after the offset has been set beyond the end * of the file. * * @param pos the offset position, measured in bytes from the * beginning of the file, at which to set the file * pointer. * @exception IOException if {@code pos} is less than * {@code 0} or if an I/O error occurs. */ public void seek(long pos) throws IOException { if (pos < 0) { throw new IOException("Negative seek offset"); } else { seek0(pos); } } private native void seek0(long pos) throws IOException;
五、HTTP文件断点续传时序图
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。