使用 `read` 函数读取文件空洞(hole)部分时,读取到的内容会被系统填充为 `'\0'`(即零字节)。文件空洞是稀疏文件中未实际分配磁盘空间的区域,但逻辑上表现为连续的零字节。
1.在指定空洞部分后,写入数据
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = open("hole_file", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open failed");
return 1;
}
// 写入初始数据 "hello"
write(fd, "hello", 5);
// 跳过 1MB 创建空洞
lseek(fd, 1 * 1024 *1024, SEEK_CUR);
// 写入末尾数据 "world"
write(fd, "world", 5);
close(fd);
return 0;
}
2. 读取空洞部分并验证内容
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = open("hole_file", O_RDONLY);
if (fd == -1) {
perror("open failed");
return 1;
}
// 定位到空洞起始位置(即 "hello" 之后)
lseek(fd, 5, SEEK_SET);
// 读取 10MB 空洞部分
char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
// 检查内容是否全为 0
int is_zero = 1;
for (int i = 0; i < bytes_read; i++) {
if (buffer[i] != 0) {
is_zero = 0;
break;
}
}
if (is_zero) {
printf("Hole content: All zeros.\n");
} else {
printf("Hole content: Non-zero data.\n");
}
close(fd);
return 0;
}
#### 运行结果
$ gcc create_hole.c -o create_hole && ./create_hole
$ gcc read_hole.c -o read_hole && ./read_hole
Hole content: All zeros.
### 关键说明
1. **文件空洞的物理存储**:
- 空洞部分不会占用实际磁盘空间(通过 `du -h hole_file` 可验证),但逻辑上表现为连续的零字节。
- 例如,上述示例文件的总逻辑大小为 `5 + 1024k + 5`,但物理大小仅约为 `1MB`(取决于文件系统)。
2. **读取行为**:
- 使用 `read` 读取空洞时,系统会返回零字节填充的缓冲区,与普通未初始化内存不同。
- 空洞的零值由文件系统动态生成,而非实际存储的数据。
3. **应用场景**:
- 稀疏文件常用于虚拟机磁盘镜像或数据库预分配空间,以节省物理存储。