一、壓縮檔
我們的程式要用到了zip壓縮,就需要自己將幾個zip相關檔案加入到工程中
zlib.h zconf.h zlib.lib 這些可以自己上網下載 http://d.download.csdn.net/down/2344459/mryeze
在程式中要將 兩個.h檔案 add to project。然後聲明引入lib
#include "zlib.h"//壓縮檔相關<br />#include "zconf.h"<br />#pragma comment(lib,"zlib.lib")
這些工作只是為了使程式中的關鍵函數compress 能夠使用
之後就寫我們的代碼了,原始碼是網上找的,自己在做的時候,對其做了一點修改,使其能直接運行。
HANDLE hFile, hFileToWrite;</p><p>CString strFilePath = "C:/aaa.txt"; //要壓縮的檔案的路徑<br /> // 下載的原始碼中尾碼名為rar,經測試無法開啟</p><p>//開啟要進行壓縮的檔案<br />hFile = CreateFile(strFilePath, // file name<br />GENERIC_READ, // open for reading<br />FILE_SHARE_READ, // share for reading<br />NULL, // no security<br />OPEN_EXISTING, // existing file only<br />FILE_ATTRIBUTE_NORMAL, // normal file<br />NULL<br />); // no attr. template<br />if (hFile == INVALID_HANDLE_VALUE)<br />{<br />AfxMessageBox("Could not open file to read"); // process error<br />return;<br />}</p><p>HANDLE hMapFile, hMapFileToWrite;<br />//建立一個檔案對應<br />hMapFile = CreateFileMapping(hFile, // Current file handle.<br />NULL, // Default security.<br />PAGE_READONLY, // Read/write permission.<br />0, // Max. object size.<br />0, // Size of hFile.<br />"ZipTestMappingObjectForRead"<br />); // Name of mapping object.<br />if (hMapFile == NULL)<br />{<br />AfxMessageBox("Could not create file mapping object");<br />return;<br />}</p><p>LPVOID lpMapAddress, lpMapAddressToWrite;<br />//建立一個檔案對應的視圖用來作為source<br />lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.<br />FILE_MAP_READ, // Read/write permission<br />0, // Max. object size.<br />0, // Size of hFile.<br />0); // Map entire file.<br />if (lpMapAddress == NULL)<br />{<br />AfxMessageBox("Could not map view of file");<br />return;<br />}</p><p>DWORD dwFileLength,dwFileLengthToWrite;<br />dwFileLength = GetFileSize(hFile, NULL); //擷取檔案的大小</p><p>//m_dwSourceFileLength = dwFileLength;</p><p>//因為壓縮函數的輸出緩衝必須比輸入大0.1% + 12 然後一個DWORD 用來儲存壓縮前的大小,<br />// 解壓縮的時候用,當然還可以儲存更多的資訊,這裡用不到<br />dwFileLengthToWrite = (double)dwFileLength*1.001 + 12 +sizeof(DWORD);</p><p>//以下是建立一個檔案,用來儲存壓縮後的檔案<br />hFileToWrite = CreateFile("C:/demoFile.txt", // demoFile.rar<br />GENERIC_WRITE|GENERIC_READ, // open for writing<br />0, // do not share<br />NULL, // no security<br />CREATE_ALWAYS, // overwrite existing<br />FILE_ATTRIBUTE_NORMAL , // normal file<br />NULL); // no attr. template<br />if (hFileToWrite == INVALID_HANDLE_VALUE)<br />{<br />AfxMessageBox("Could not open file to write"); // process error<br />return;<br />}</p><p>//為輸出檔案 建立一個檔案對應<br />hMapFileToWrite = CreateFileMapping(hFileToWrite, // Current file handle.<br />NULL, // Default security.<br />PAGE_READWRITE, // Read/write permission.<br />0, // Max. object size.<br />dwFileLengthToWrite, // Size of hFile.<br />"ZipTestMappingObjectForWrite"); // Name of mapping object.<br />if (hMapFileToWrite == NULL)<br />{<br />AfxMessageBox("Could not create file mapping object for write");<br />return;<br />}</p><p>//為輸出檔案 建立一個檔案對應視圖<br />lpMapAddressToWrite = MapViewOfFile(hMapFileToWrite, //Handle to mapping<br />FILE_MAP_WRITE, // Read/write permission 0, // Max. object size.<br />0, // Size of hFile.<br />0,<br />0<br />); // Map entire file.<br />if (lpMapAddressToWrite == NULL)<br />{<br />AfxMessageBox("Could not map view of file");<br />return;<br />}</p><p>//這裡是將壓縮前的大小儲存在檔案的第一個DWORD 裡面<br />LPVOID pBuf = lpMapAddressToWrite;<br />(*(DWORD*)pBuf) = dwFileLength;<br />pBuf = (DWORD*)pBuf + 1;</p><p>//這裡就是最重要的,zlib 裡面提供的一個方法,將源緩衝的資料壓縮至目的緩衝<br />//原形如下:<br />//int compress (Bytef *dest, uLongf *destLen, const Bytef*source, uLong sourceLen);<br />//參數destLen 返回實際壓縮後的檔案大小。<br />compress((Bytef*)pBuf,&dwFileLengthToWrite, (Bytef*)lpMapAddress, dwFileLength);</p><p>UnmapViewOfFile(lpMapAddress);<br />CloseHandle(hMapFile);<br />CloseHandle(hFile);<br />UnmapViewOfFile(lpMapAddressToWrite);<br />CloseHandle(hMapFileToWrite);</p><p>//這裡將檔案大小重新設定一下<br />SetFilePointer(hFileToWrite,dwFileLengthToWrite + sizeof(DWORD) ,NULL,FILE_BEGIN);<br />SetEndOfFile(hFileToWrite);<br />CloseHandle(hFileToWrite);
運行程式後,將aaa.txt檔案壓縮成功了。
二、解壓檔案
解壓檔案的思路和壓縮差不多,其中的區別就是
1. 輸出檔案緩衝區大小的設定
zip為:
//因為壓縮函數的輸出緩衝必須比輸入大0.1% + 12 然後一個DWORD 用來儲存壓縮前的大小,<br />// 解壓縮的時候用,當然還可以儲存更多的資訊,這裡用不到<br />dwFileLengthToWrite = (double)dwFileLength*1.001 + 12 +sizeof(DWORD);
upzip為:
dwFileLengthToWrite = (*(DWORD*)lpMapAddress);
2 compress 與 uncompress函數
這個是必須的了!
compress((Bytef*)pBuf,&dwFileLengthToWrite, (Bytef*)lpMapAddress, dwFileLength);
uncompress((Bytef*)pBuf,&dwFileLengthToWrite, (Bytef*)pSourceBuf, dwFileLength);
還是提供原始碼
HANDLE hFile, hFileToWrite;<br />CString strFilePath="C:/demoFile.txt";<br />//開啟要進行解壓縮的檔案<br />hFile = CreateFile(strFilePath, // file name<br />GENERIC_READ, // open for reading<br />FILE_SHARE_READ, // share for reading<br />NULL, // no security<br />OPEN_EXISTING, // existing file only<br />FILE_ATTRIBUTE_NORMAL, // normal file<br />NULL<br />); // no attr. template<br />if (hFile == INVALID_HANDLE_VALUE)<br />{<br />AfxMessageBox("Could not open file to read"); // process error<br />return;<br />}<br />HANDLE hMapFile, hMapFileToWrite;<br />//建立一個檔案對應<br />hMapFile = CreateFileMapping(hFile, // Current file handle.<br />NULL, // Default security.<br />PAGE_READONLY, // Read/write permission.<br />0, // Max. object size.<br />0, // Size of hFile.<br />"ZipTestMappingObjectForRead"); // Name of mapping object.<br />if (hMapFile == NULL)<br />{<br />AfxMessageBox("Could not create file mapping object");<br />return;<br />}<br />LPVOID lpMapAddress, lpMapAddressToWrite;<br />//建立一個檔案對應的視圖用來作為source<br />lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping<br />FILE_MAP_READ, // Read/write permission<br />0, // Max. object size.<br />0, // Size of hFile.<br />0); // Map entire file.<br />if (lpMapAddress == NULL)<br />{<br />AfxMessageBox("Could not map view of file");<br />return;<br />}<br />DWORD dwFileLength,dwFileLengthToWrite;<br />dwFileLength = GetFileSize(hFile, NULL) - sizeof(DWORD);<br />//因為壓縮函數的輸出緩衝必須比輸入大0.1% + 12 然後一個DWORD 用來儲存壓縮前的大小,<br />// 解壓縮的時候用,當然還可以儲存更多的資訊,這裡用不到<br />// dwFileLengthToWrite = (double)dwFileLength*1.001 + 12 +sizeof(DWORD);<br />dwFileLengthToWrite = (*(DWORD*)lpMapAddress);<br />LPVOID pSourceBuf = lpMapAddress;<br />pSourceBuf = (DWORD*)pSourceBuf + 1;<br />//以下是建立一個檔案,用來儲存壓縮後的檔案<br />hFileToWrite = CreateFile("C:/UnZipFile.txt", // create demo.gz<br />GENERIC_WRITE|GENERIC_READ, // open for writing<br />0, // do not share<br />NULL, // no security<br />CREATE_ALWAYS, // overwrite existing<br />FILE_ATTRIBUTE_NORMAL , // normal file<br />NULL<br />); // no attr. template<br />if (hFileToWrite == INVALID_HANDLE_VALUE)<br />{<br />AfxMessageBox("Could not open file to write"); //process error<br />return;<br />}<br />hMapFileToWrite = CreateFileMapping(hFileToWrite, // Currentfile handle.<br />NULL, // Default security.<br />PAGE_READWRITE, // Read/write permission.<br />0, // Max. object size.<br />dwFileLengthToWrite, // Size of hFile.<br />"ZipTestMappingObjectForWrite"); // Name of mapping object.<br />if (hMapFileToWrite == NULL)<br />{<br />AfxMessageBox("Could not create file mapping object for write");<br />return;<br />}<br />lpMapAddressToWrite = MapViewOfFile(hMapFileToWrite, //Handle to mapping object.<br />FILE_MAP_WRITE, // Read/write permission<br />0, // Max. object size.<br />0, // Size of hFile.<br />0<br />); // Map entire file.<br />if (lpMapAddressToWrite == NULL)<br />{<br />AfxMessageBox("Could not map view of file");<br />return;<br />}<br />//這裡是將壓縮前的大小儲存在檔案的第一個DWORD 裡面<br />LPVOID pBuf = lpMapAddressToWrite;<br />//這裡就是最重要的,zlib 裡面提供的一個方法,將源緩衝的資料壓縮至目的緩衝<br />//原形如下:<br />//int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);<br />//參數destLen 返回實際壓縮後的檔案大小。<br />uncompress((Bytef*)pBuf,&dwFileLengthToWrite, (Bytef*)pSourceBuf, dwFileLength);<br />UnmapViewOfFile(lpMapAddress);<br />CloseHandle(hMapFile);<br />CloseHandle(hFile);<br />UnmapViewOfFile(lpMapAddressToWrite);<br />CloseHandle(hMapFileToWrite);<br />//這裡將檔案大小重新設定一下<br />SetFilePointer(hFileToWrite,dwFileLengthToWrite,NULL,FILE_BEGIN);<br />SetEndOfFile(hFileToWrite);<br />CloseHandle(hFileToWrite);
運行效果如下: