windows稀疏文件
? 稀疏文件(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 ); ?例子代碼如下:?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> 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的windows稀疏文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图结构练习——判断给定图是否存在合法拓扑
- 下一篇: LinkedHashSet类