• 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

  • 相关阅读:
    [转]double free or corruption (!prev): 0x080644c8 ***
    linux sleep用法
    ubuntu的终端下修改IP、MAC、DNS及GATE
    jmeter mina2总结
    double free or corruption (!prev): 0x080644c8 ***
    jmeter最简单使用
    超级详细Tcpdump 的用法
    eclipse下打开jmeter源码
    Jmeter 命令行选项目录
    JavaScript的一些实用技巧收藏
  • 原文地址:https://www.cnblogs.com/dvwei/p/3372935.html
Copyright © 2020-2023  润新知