lseek函数与文件空洞
2013-10-16 21:14 DVwei 阅读(1079) 评论(0) 编辑 收藏 举报在UNIX/LINUX系统中,文件位移量可以大于文件的当前长度,这种情况下向文件中写入数据就会产生文件空洞(hole),这些没写入数据的文件空洞部分默认会被0填满。虽然这些文件空洞并没有实际的数据,但是它们仍然占据硬盘空间。
在Windows下同样支持这种文件空洞,以下简单的代码产生一个6KB的空洞文件:
#include <afx.h> #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { CFile testFile(_T("D:\\test"), CFile::modeCreate | CFile::modeWrite); CHAR buff[1024]; memset(buff, 12, 1024); testFile.Write(buff, 1024); testFile.Seek(1024 * 3, CFile::begin); memset(buff, 22, 1024); testFile.Write(buff, 1024); testFile.Seek(1024 * 5, CFile::begin); memset(buff, 20, 1024); testFile.Write(buff, 1024); testFile.Close(); return 0; }
用Sublime Text2打开,可以发现中间两部分是NULL(0),这就是文件空洞
从代码地图上可以看到此文件有3KB是空的:
Windows下的NTFS文件系统还支持文件空洞的压缩,那些0都是无用的数据,却又占据了空间资源,NTFS文件空洞的压缩算法可以释放这些0字节的空间。这种文件被称为稀疏文件,通过指定DeviceIoControl函数
BOOL WINAPI DeviceIoControl(
_In_ HANDLE hDevice,
_In_ DWORD dwIoControlCode,
_In_opt_ LPVOID lpInBuffer,
_In_ DWORD nInBufferSize,
_Out_opt_ LPVOID lpOutBuffer,
_In_ DWORD nOutBufferSize,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
设置FSCTL_SET_SPARSE标记可以产生稀疏文件,以下代码是一个例子:
hFile = CreateFile("tmp_file", GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, CREATE_ALWAYS,0,NULL); DWORD dwTemp; DeviceIoControl(hFile,FSCTL_SET_SPARSE, NULL,0,NULL,0,&dwTemp,NULL); SetFilePointer(hFile, 0x100000, NULL, FILE_BEGIN); WriteFile(hFile,"123", 3, &nWritten, NULL); SetEndOfFile(hFile); CloseHandle(hFile);
通过GetFileInformationByHandle可以查看文件是否为稀疏文件:
BOOL WINAPI GetFileInformationByHandle(
_In_ HANDLE hFile,
_Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation
);
FSCTL_SET_SPARSE
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)