稀疏文件(Sparse File), 指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却一样的占用我们的空间,针对此,WINNT 3.51中的NTFS文件系统对此进行了优化,那些无用的0字节被用一定的算法压缩起来,使得这些0字节不再占用那么多的空间,在你声明一个很大的稀疏文件时(例如 100GB),这个文件实际上并不需要占用这么大的空间,因为里面大都是无用的0数据,那么,NTFS对稀疏文件的压缩算法可以释放这些无用的0字节空间, 可以说这是对磁盘占用空间以及效率的一种优化,记住,FAT32上并不支持稀疏文件的压缩(至少我在自己机子上测试得出如此结论)。

这里,我们将粗略的介绍:

1,如何判断一个磁盘是否支持稀疏文件。
2,如何判断一个文件是否是稀疏文件。
3,如何产生一个稀疏文件。
4,假如系统支持稀疏文件,如何声明这个文件是稀疏文件。

因为这是我工作中出现的问题,所以可能不会深究里面的算法和操作系统机制,但是文章末尾会附上参考资料。
 若有问题,可以联系我 shawn.huang@protegrity.com(工作邮箱)  或者 lonestep@gmail.com(私人邮箱)

1.1   判断一个磁盘是否是稀疏文件。

我们可以通过一个系统函数GetVolumeInformation 来判断某个磁盘是否支持稀疏文件的压缩。MSDN中的函数原型如下:

GetVolumeInformation

The GetVolumeInformation function retrieves information about a file system and volume that have a specified root directory.

BOOL GetVolumeInformation(
LPCTSTR lpRootPathName,LPTSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,LPDWORD lpFileSystemFlags,LPTSTR lpFileSystemNameBuffer,DWORD nFileSystemNameSize
);

我们只要把查询到的Flag 跟 FILE_SUPPORTS_SPARSE_FILES 位与(&),便可以知道该磁盘是否支持。这是从我的工具集(toolset)里摘录的例子代码:
    CHAR szVolName[MAX_PATH], szFsName[MAX_PATH];     DWORD dwSN, dwFSFlag, dwMaxLen, nWritten;     BOOL bSuccess;     HANDLE hFile;     bSuccess = GetVolumeInformation(NULL,         szVolName,         MAX_PATH,         &dwSN,          &dwMaxLen,          &dwFSFlag,          szFsName,         MAX_PATH);     if (!bSuccess) {         printf("errno:%d", GetLastError());         return -1;     }     printf("vol name:%s /t fs name:%s sn: %d./n", szVolName, szFsName, dwSN);     if (dwFSFlag&FILE_SUPPORTS_SPARSE_FILES) {         printf("support sparse file./n");     }else{         printf("no support sparse file./n");     }

2.1 如何判断一个文件是否是稀疏文件。我们可以通过 GetFileInformationByHandle()函数来判断一个文件是否是稀疏文件。这是MSDN里面的定义。

The GetFileInformationByHandle function retrieves file information for the specified file.
BOOL GetFileInformationByHandle(
HANDLE hFile,LPBY_HANDLE_FILE_INFORMATION lpFileInformation
);
 
例子代码如下:
 
 
3.1, 如何产生一个稀疏文件并声明该文件是稀疏文件。
   大部分文件,在你改变它的EndOfFile的时候,中间的空白会被操作系统填0,也就是说,如果你用SetFilePointer() 和SetEndOfFile()来
产生一个很大的文件,那么这个文件它占用的是真正的磁盘空间,即使里面全是0,因为系统默认的会在DeviceIoControl()中的ControlCode里用
FSCTL_SET_ZERO_DATA标记,这个标记使得那些文件空洞被0所填充。为了节省磁盘空间,我们必须把一个文件声明为稀疏文件,以便让系统
把那些无用的0字节压缩,并释放相应的磁盘空间,方法如下:
 
注意到FSCTL_SET_SPARSE这个标记了吗?正是这个标记,告诉系统该文件是稀疏文件,如果该文件所在的磁盘支持稀疏
文件的压缩,则系统会释放不必要的0字节空间。你可以用这个方法创建一个100GB得文件试一下(示例里是1M),记得右键看看文件属性
里的‘大小’和占用空间,它被声明为100GB,但是实际上那些0字节基本不占用空间,而你写入的“123”是占用实际的
磁盘空间的。
   注意:在FAT32得磁盘里,因为没有对SPARSE FILE得支持,所以您创建的空洞文件全部被填零,即使你声明它是一个稀疏
文件,也没有任何作用,您声明这个文件多大,它就占用多大的空间。
   另外,如果您编译 DeviceIoControl这个函数出现 "'FSCTL_SET_SPARSE' : undeclared identifier"之类的情况
请这样做:
#include <windows.h>
#define   _WIN32_WINNT         0x0501
#include <Winioctl.h>
    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);

HANDLE hFile; BY_HANDLE_FILE_INFORMATION stFileInfo; //Open/create file to get the file handle hFile = CreateFile(); //Get the file information GetFileInformationByHandle(hFile, &stFileInfo); if(stFileInfo.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) {     //Sparse file }else{    //Not sparse file }
												

windows稀疏文件相关推荐

  1. Linux和Windows稀疏文件拷贝移动

    1. 概述 稀疏文件(英语:sparse file)是一种计算机文件,它能尝试在文件内容大多为空时更有效率地使用文件系统的空间.它的原理是以简短的信息(元数据)表示空数据块,而不是在在磁盘上占用实际空 ...

  2. live messenger与稀疏文件—Sparse File Bit

    今天进行磁盘整理,发现一个奇怪的文件SimilarityTable_1:下面是我的C盘整理后的结果 卷   (C:)     卷的大小                                  ...

  3. WINHEX的比较、同步功能加上NTFS对稀疏文件的支持

    [原创]如何快速地分析RAID信息在每块盘上的记录方式,如何快速地确定系统的实质读写操作.WINHEX是一个非常好的软件,通过其比较和同步功能加上NTFS对稀疏文件的支持,看看怎么实现上述设想... ...

  4. Windows启动文件

    Windows启动文件 Files Used in the Windows 2000 Boot Process File Location Boot stage Ntldr System partit ...

  5. Python打包工具Pyintealler打包py文件为windows exe文件过程及踩坑记录+实战例子

    Python打包工具Pyintealler打包py文件为windows exe文件过程及踩坑记录+实战例子 目录 Python打包工具Pyintealler打包py文件为windows exe文件过程 ...

  6. linux下压缩并分割稀疏文件

    稀疏文件是指一个文件中大部分内容都是空字符的文件. 如虚拟机创建的100G的磁盘文件是,但系统不会马上分割出100G的空间,而是仅标识出虚拟硬盘文件是稀疏文件,待到数据存储时,再分配空间,这样可以大大 ...

  7. Windows注册文件类型信息的学习心得

    前一阵做系统注册文件类型图标的提取工具,本来以为使用SHGetFileInfo()函数只能获取指定文件名的图标,没想到还能获取指定扩展名关联的图标,因此绕了一个大弯路去研究注册表.虽然花费了很多时间, ...

  8. 提取Windows用户密钥文件cachedump

    2019独角兽企业重金招聘Python工程师标准>>> 提取Windows用户密钥文件cachedump Windows系统将用户信息和密钥存储在系统存档文件(System hive ...

  9. Windows删除文件时显示找不到该项目

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Hanniel/article/details/78346209 当在Windows删除文件时出现找不 ...

最新文章

  1. 比特币的锁定脚本与解锁脚本
  2. 道哥自述:为什么弹性安全网络将诞生最大的人工智能?
  3. 怎么安装python3.6.2_centos7.2下安装python3.6.2
  4. sqlserver存储过程入门之 游标
  5. android中设置菜单栏,android – 菜单项没有显示在操作栏
  6. 苹果的消息是从服务器接收数据,iOS 消息推送原理及简单实现
  7. python调用百度智能云API请求(以自然语言处理——词法分析为例)
  8. NDoc修改手记(一)
  9. 海量数据挖掘MMDS week6: 支持向量机Support-Vector Machines,SVM
  10. CSDN的积分如何获取(转)
  11. Java POJO 自动生成器
  12. ERStudio如何显示entity的tableName(表名的英文)和defaultColumnName(英文字段名)
  13. 全国各地城市FM调频电台频率列表(上海北京广州深圳长沙武汉重庆)
  14. xilinx PCIe PIO工程仿真及验证
  15. elasticsearch安装部署
  16. 今天一篇文章告诉你Python 自动化测试 必会模块 Unittest
  17. 惠不停返利网:掀起购物返利高潮
  18. 提交模式窗口后,刷新父窗口数据+获取frameset中各模块中数据
  19. 关于skb_make_writable()函数
  20. js之浏览器本地存储webstorage

热门文章

  1. mysql myisam 支持事务吗_第三章(附)mysql表类型MyISAM和InnoDB区别(决定了是否支持事务)...
  2. vue if判断_VUE学习记录2
  3. IOC操作Bean管理XML方式(FactoryBean)
  4. Nginx的配置实例(反向代理实例 )
  5. Linux的Xshell连接Centos7能Ping通但无法连接问题[ssh(d)+firewall(d)]【转载转载转载】
  6. 觅凤c语言教程,C语言程序设计教程 第1章.ppt
  7. 数学C语言编程,数学规划 (最速下降法,c语言编程).doc
  8. springboot用户管理系统_Springboot优秀开源项目
  9. 卷组删除pv_如何安全的删除Linux LVM中的PV物理卷(硬盘或分区)
  10. R 语言怎么保存工作目录到当前路径_【R语言基础】01.R语言软件环境搭建及常用操作...