lseek函数与文件空洞

  在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

转载于:https://www.cnblogs.com/dvwei/p/3372935.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值