• 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

  • 相关阅读:
    望图知意BlogPatrol又挂了
    看你知道不知道之-制作数据字典
    mount: none already mounted or /cgroup busy
    [zz]OpenStack中虚拟机的监控
    guestfs
    Ubuntu 10.04 wine 中运行某个门
    [zz]Wine完全使用指南——从基本到高级
    [zz]史上最快消息内核——ZeroMQ
    [zz]OpenStack Compute(Nova)功能分析
    [zz][技术] 完美使用 WINE 来运行 RTX ,QQ
  • 原文地址:https://www.cnblogs.com/dvwei/p/3372935.html
Copyright © 2020-2023  润新知