nfs共享存储web项目集群的一次下载流为空FIleChannel空洞bug

参考:

https://blog.csdn.net/will_awoke/article/details/25972361
http://ifeve.com/file-channel/

FileChannel对象是线程安全(thread-safe)的。多个进程可以在同一个实例上并发调用方法而不会引起任何问题,不过并非所有的操作都是多线程的(multithreaded)。影响通道位置或者影响文件大小的操作都是单线程的(single-threaded)。如果有一个线程已经在执行会影响通道位置或文件大小的操作,那么其他尝试进行此类操作之一的线程必须等待。并发行为也会受到底层的操作系统或文件系统影响。

同大多数I/O相关的类一样,FileChannel是一个反映Java虚拟机外部一个具体对象的抽象。FileChannel类保证同一个Java虚拟机上的所有实例看到的某个文件的视图均是一致的,但是Java虚拟机却不能对超出它控制范围的因素提供担保。通过一个FileChannel实例看到的某个文件的视图同通过一个外部的非Java进程看到的该文件的视图可能一致,也可能不一致。多个进程发起的并发文件访问的语义高度取决于底层的操作系统和(或)文件系统。一般而言,由运行在不同Java虚拟机上的FileChannel对象发起的对某个文件的并发访问和由非Java进程发起的对该文件的并发访问是一致的。

文件空洞(file hole)
在UNIX文件操作中,文件位移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将延长该文件,并在文件中构成一个空洞,这一点是允许的。位于文件中但没有写过的字节都被设为 0。
如果 offset 比文件的当前长度更大,下一个写操作就会把文件“撑大(extend)”。这就是所谓的在文件里创造“空洞(hole)”。没有被实际写入文件的所有字节由重复的 0 表示。空洞是否占用硬盘空间是由文件系统(file system)决定的。
用ls查看的文件大小是将空洞算在内的。
cp命令拷贝的文件,空洞部分不拷贝,所以生成的同样文件占用磁盘空间小。
用read读取空洞部分读出的数据是0,所以如果用read和write拷贝一个有空洞的文件,那么最终得到的文件没有了空洞,空洞部分都被0给填充了,文件占用的磁盘空间就大了。不过文件大小不变。
空洞文件作用很大,例如迅雷下载文件,在未下载完成时就已经占据了全部文件大小的空间,这时候就是空洞文件。下载时如果没有空洞文件,多线程下载时文件就都只能从一个地方写入,这就不是多线程了。如果有了空洞文件,可以从不同的地址写入,就完成多线程的优势任务。>

本次bug 最终以判断是否读完做了修改,期望不会引起其他问题。
nfs共享存储web项目集群的一次下载流为空FIleChannel空洞bug_第1张图片

你可能感兴趣的:(学习,工作中的问题)