网站设计理念怎么写,外贸公司有必要建设网站吗,网站动态页面怎么做,wordpress 评论 作者稀疏文件(Sparse File), 指的是文件中出现大量的0数据#xff0c;这些数据对我们用处不大#xff0c;但是却一样的占用我们的空间#xff0c;针对此#xff0c;WINNT 3.51中的NTFS文件系统对此进行了优化#xff0c;那些无用的0字节被用一定的算法压缩起来#xff0c;使得… 稀疏文件(Sparse File), 指的是文件中出现大量的0数据这些数据对我们用处不大但是却一样的占用我们的空间针对此WINNT 3.51中的NTFS文件系统对此进行了优化那些无用的0字节被用一定的算法压缩起来使得这些0字节不再占用那么多的空间在你声明一个很大的稀疏文件时(例如 100GB)这个文件实际上并不需要占用这么大的空间因为里面大都是无用的0数据那么NTFS对稀疏文件的压缩算法可以释放这些无用的0字节空间 可以说这是对磁盘占用空间以及效率的一种优化记住FAT32上并不支持稀疏文件的压缩至少我在自己机子上测试得出如此结论。 这里我们将粗略的介绍 1如何判断一个磁盘是否支持稀疏文件。 2如何判断一个文件是否是稀疏文件。 3如何产生一个稀疏文件。 4假如系统支持稀疏文件如何声明这个文件是稀疏文件。 因为这是我工作中出现的问题所以可能不会深究里面的算法和操作系统机制但是文章末尾会附上参考资料。 若有问题可以联系我 shawn.huangprotegrity.com(工作邮箱) 或者 lonestepgmail.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 (dwFSFlagFILE_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
);例子代码如下 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