稀疏文件

转载 2012年03月24日 11:34:07
2011-07-04 16:12

稀疏文件(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.

 

BOOLGetVolumeInformation(

LPCTSTRlpRootPathName,

LPTSTRlpVolumeNameBuffer,

DWORDnVolumeNameSize,

LPDWORDlpVolumeSerialNumber,

LPDWORDlpMaximumComponentLength,

LPDWORDlpFileSystemFlags,

LPTSTRlpFileSystemNameBuffer,

DWORDnFileSystemNameSize

);

 


我们只要把查询到的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.

BOOLGetFileInformationByHandle(

HANDLEhFile,

LPBY_HANDLE_FILE_INFORMATIONlpFileInformation

);

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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
}


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

3.1, 如何产生一个稀疏文件并声明该文件是稀疏文件。 大部分文件,在你改变它的EndOfFile的时候,中间的空白会被操作系统填0,也就是说,如果你用SetFilePointer() 和SetEndOfFile()来产生一个很大的文件,那么这个文件它占用的是真正的磁盘空间,即使里面全是0,因为系统默认的会在DeviceIoControl()中的ControlCode里用FSCTL_SET_ZERO_DATA标记,这个标记使得那些文件空洞被0所填充。为了节省磁盘空间,我们必须把一个文件声明为稀疏文件,以便让系统把那些无用的0字节压缩,并释放相应的磁盘空间,方法如下:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    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);

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

注意到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>


稀疏文件(sparse-files)生成汇总

稀疏文件文件这个东东,最开始知道是在学Oracle temp表空间。因为 Oracle 临时表空间的数据文件ls和du出来,大小不一致,后来才知道, 这东东是稀疏文件的特性。 这玩意主要是先跟系统把整...
  • xcltapestry
  • xcltapestry
  • 2014年01月01日 22:56
  • 2281

稀疏文件(Sparse File)

稀疏文件,这是UNIX类和NTFS等文件系统的一个特性。 开始时,一个稀疏文件不包含用户数据,也没有分配到用来存储用户数据的磁盘空间。当数据被写入稀疏文件时,NTFS逐渐地为其分配磁盘空间。一个稀疏...
  • tiandyoin
  • tiandyoin
  • 2015年02月02日 10:30
  • 5074

Tensorflow踩坑记

这里是踩坑纪录,大家如果想看教程的话请出门右转~从前有个小孩,正在学习TF,一开始,写了个逻辑回归的优化程序:import tensorflow as tf import numpy as npx=t...
  • hejunqing14
  • hejunqing14
  • 2016年09月28日 15:38
  • 7984

第一个tensorflow小程序——异或门实现

代码:#author@chengxiaona import tensorflow as tf import numpy as np#输入训练数据,这里是python的list, 也可以定义为numpy...
  • chengxiaona
  • chengxiaona
  • 2017年10月15日 16:32
  • 653

TypeError: Can not convert a float32 into a Tensor or Operation.

错误TypeError: Can not convert a float32 into a Tensor or Operation. # 类型错误:不能将一个浮动32转换为一个张量或操作。TypeEr...
  • FontThrone
  • FontThrone
  • 2017年08月09日 21:03
  • 2267

【转】NTFS Sparse Files For Programmers(稀疏文件)

稀疏文件 文件空洞
  • zdragon2002
  • zdragon2002
  • 2011年01月26日 12:15
  • 2192

TensorFlow踩坑记:Can not convert a ndarray into a Tensor or Operation.

今天掉进一坑,爬了好一会踩爬出来,先将问题记录一些,谨以此献给出现同样错误的同学,错误:Can not convert a ndarray into a Tensor or Operation. “...
  • Michael__Corleone
  • Michael__Corleone
  • 2018年01月08日 21:28
  • 171

tensorflow 变量生成 变量管理 tf.Variable & tf.get_variable & tf.variable_scope

____tz_zs学习笔记 tf.Variable 官网api:https://www.tensorflow.org/api_docs/python/tf/Variable def __...
  • tz_zs
  • tz_zs
  • 2017年07月13日 17:27
  • 1520

稀疏文件Sparse File

引入稀疏文件(sparse file)的目的是有效的利用文件系统空间(磁盘空间)。当文件没有实际数据时,首先将元数据/metadata(代表了空blocks)写入磁盘,而不是用空数据(0)填充磁盘。而...
  • iCode0410
  • iCode0410
  • 2014年09月24日 10:14
  • 1483

windows稀疏文件

稀疏文件(Sparse File), 指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却一样的占用我们的空间,针对此,WINNT 3.51中的NTFS文件系统对此进行了优化,那些无用的0字节...
  • u014805066
  • u014805066
  • 2017年10月17日 17:06
  • 120
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:稀疏文件
举报原因:
原因补充:

(最多只允许输入30个字)