windows稀疏文件
? 稀疏文件(Sparse File), 指的是文件中出現(xiàn)大量的0數(shù)據(jù),這些數(shù)據(jù)對(duì)我們用處不大,但是卻一樣的占用我們的空間,針對(duì)此,WINNT 3.51中的NTFS文件系統(tǒng)對(duì)此進(jìn)行了優(yōu)化,那些無(wú)用的0字節(jié)被用一定的算法壓縮起來(lái),使得這些0字節(jié)不再占用那么多的空間,在你聲明一個(gè)很大的稀疏文件時(shí)(例如 100GB),這個(gè)文件實(shí)際上并不需要占用這么大的空間,因?yàn)槔锩娲蠖际菬o(wú)用的0數(shù)據(jù),那么,NTFS對(duì)稀疏文件的壓縮算法可以釋放這些無(wú)用的0字節(jié)空間, 可以說(shuō)這是對(duì)磁盤(pán)占用空間以及效率的一種優(yōu)化,記住,FAT32上并不支持稀疏文件的壓縮(至少我在自己機(jī)子上測(cè)試得出如此結(jié)論)。
????? 這里,我們將粗略的介紹:
1,如何判斷一個(gè)磁盤(pán)是否支持稀疏文件。
2,如何判斷一個(gè)文件是否是稀疏文件。
3,如何產(chǎn)生一個(gè)稀疏文件。
4,假如系統(tǒng)支持稀疏文件,如何聲明這個(gè)文件是稀疏文件。
???? 因?yàn)檫@是我工作中出現(xiàn)的問(wèn)題,所以可能不會(huì)深究里面的算法和操作系統(tǒng)機(jī)制,但是文章末尾會(huì)附上參考資料。
?若有問(wèn)題,可以聯(lián)系我?shawn.huang@protegrity.com(工作郵箱)??或者?lonestep@gmail.com(私人郵箱)?
1.1?? 判斷一個(gè)磁盤(pán)是否是稀疏文件。
我們可以通過(guò)一個(gè)系統(tǒng)函數(shù)GetVolumeInformation?來(lái)判斷某個(gè)磁盤(pán)是否支持稀疏文件的壓縮。MSDN中的函數(shù)原型如下:
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 ); 我們只要把查詢(xún)到的Flag 跟 FILE_SUPPORTS_SPARSE_FILES 位與(&),便可以知道該磁盤(pán)是否支持。這是從我的工具集(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 如何判斷一個(gè)文件是否是稀疏文件。我們可以通過(guò) GetFileInformationByHandle()函數(shù)來(lái)判斷一個(gè)文件是否是稀疏文件。這是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, 如何產(chǎn)生一個(gè)稀疏文件并聲明該文件是稀疏文件。 大部分文件,在你改變它的EndOfFile的時(shí)候,中間的空白會(huì)被操作系統(tǒng)填0,也就是說(shuō),如果你用SetFilePointer() 和SetEndOfFile()來(lái)產(chǎn)生一個(gè)很大的文件,那么這個(gè)文件它占用的是真正的磁盤(pán)空間,即使里面全是0,因?yàn)橄到y(tǒng)默認(rèn)的會(huì)在DeviceIoControl()中的ControlCode里用FSCTL_SET_ZERO_DATA標(biāo)記,這個(gè)標(biāo)記使得那些文件空洞被0所填充。為了節(jié)省磁盤(pán)空間,我們必須把一個(gè)文件聲明為稀疏文件,以便讓系統(tǒng)把那些無(wú)用的0字節(jié)壓縮,并釋放相應(yīng)的磁盤(pán)空間,方法如下:?????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這個(gè)標(biāo)記了嗎?正是這個(gè)標(biāo)記,告訴系統(tǒng)該文件是稀疏文件,如果該文件所在的磁盤(pán)支持稀疏 文件的壓縮,則系統(tǒng)會(huì)釋放不必要的0字節(jié)空間。你可以用這個(gè)方法創(chuàng)建一個(gè)100GB得文件試一下(示例里是1M),記得右鍵看看文件屬性 里的‘大小’和占用空間,它被聲明為100GB,但是實(shí)際上那些0字節(jié)基本不占用空間,而你寫(xiě)入的“123”是占用實(shí)際的 磁盤(pán)空間的。 注意:在FAT32得磁盤(pán)里,因?yàn)闆](méi)有對(duì)SPARSE FILE得支持,所以您創(chuàng)建的空洞文件全部被填零,即使你聲明它是一個(gè)稀疏文件,也沒(méi)有任何作用,您聲明這個(gè)文件多大,它就占用多大的空間。 另外,如果您編譯 DeviceIoControl這個(gè)函數(shù)出現(xiàn) "'FSCTL_SET_SPARSE' : undeclared identifier"之類(lèi)的情況請(qǐng)這樣做:#include <windows.h> #define?? _WIN32_WINNT???????? 0x0501 #include <Winioctl.h> 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的windows稀疏文件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图结构练习——判断给定图是否存在合法拓扑
- 下一篇: 分布式系统的工程化开发方法