内容简介:一步一步带你起飞 ... ...计算机是以字节(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文件断点续传时序图
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Beginning ASP.NET 4 in C# and Vb
Imar Spaanjaars / Wrox / 2010-3-19 / GBP 29.99
This book is for anyone who wants to learn how to build rich and interactive web sites that run on the Microsoft platform. With the knowledge you gain from this book, you create a great foundation to ......一起来看看 《Beginning ASP.NET 4 in C# and Vb》 这本书的介绍吧!