如何删除稀疏文件中的内容并保持其稀疏特性?
稀疏文件清除临时数据方案
最优方案:使用 fallocate 打孔
该方案原生支持保持文件稀疏特性,同时彻底清除已有数据不会残留,且不会修改文件逻辑大小,完全不影响后续内存映射IO操作,仅需要Linux 2.6.38及以上版本、以及ext4/xfs/btrfs等主流文件系统支持。
代码示例:
// 可按需传入要清除的区间偏移和长度 // 若要清空全部已写入内容,偏移设为0,长度设为文件初始的len即可 int res = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, len); if (res == -1) { // 自行补充错误处理逻辑 }
参数说明:
FALLOC_FL_PUNCH_HOLE:对指定区间打孔,释放该区间占用的磁盘块,区间变为稀疏洞,读取时返回全0,原有数据会被彻底清除不会留存。FALLOC_FL_KEEP_SIZE:保证文件逻辑大小保持不变,不会修改你之前通过ftruncate设置的大长度,后续mmap操作可以正常执行。
兼容方案:全0覆盖
如果运行环境不支持fallocate打孔,可以使用pwrite写入全0覆盖要清除的区间,主流现代文件系统会自动将全0连续块优化为稀疏洞,不占用磁盘空间。
代码示例:
// 以4KB为单位写入全0 const size_t buf_size = 4096; void *zero_buf = calloc(1, buf_size); off_t cur_offset = 0; while (cur_offset < len) { size_t write_size = (len - cur_offset) > buf_size ? buf_size : (len - cur_offset); ssize_t w_ret = pwrite(fd, zero_buf, write_size, cur_offset); if (w_ret < 0) { // 错误处理 break; } cur_offset += w_ret; } free(zero_buf);
注意:该方案性能低于fallocate打孔,部分老旧文件系统可能不会对全0块做稀疏优化,会占用实际磁盘空间。
内存映射操作适配
如果你已经对该文件完成了mmap映射,需要在执行清除操作前先调用msync同步映射区内容,或者先解除映射再执行清除操作,避免映射区缓存的旧数据和文件实际内容不一致。
内容的提问来源于stack exchange,提问作者AetX
相关产品推荐
相关产品推荐

