Zip壓縮檔 與 解壓 (MFC 檔案操作 四 )

來源:互聯網
上載者:User

一、壓縮檔

 

我們的程式要用到了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);

 

運行效果如下:

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.