码迷,mamicode.com
首页 > 其他好文 > 详细

文件压缩,文件夹压缩

时间:2020-05-19 20:26:04      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:push   dcl   osi   creation   ==   har   void   ror   off   

头文件:

#pragma once
#ifndef FILEZIPPER_HPP
#define FILEZIPPER_HPP

#include <vector>
#include <string>

#include "zip.h"
#include "iowin32.h"
#include "zlib.h"
#include "unzip.h"
#include <map>


#define WRITEBUFFERSIZE (16384)
#define MAXFILENAME (256)

class CFileZipper
{
public:
CFileZipper();
~CFileZipper();

//压缩文件
int ZipFiles(std::string &zipFileName, std::vector<std::string> files, bool bAppendFile = false, int nCompressLevel = 0);
//压缩文件
void ZipFilesFromFold(const std::string &zipFilepath,std::vector<std::string>& filevecs);
//压缩文件夹
void ZipFilesFromFold(const std::string &zipFilepath, std::string &foldpath);

private:
int isLargeFile(std::string filename);

//char *f; /* name of file to get info on */
//tm_zip *tmzip; /* return value: access, modific. and creation times */
//uLong *dt; /* dostime */
uLong filetime(const char* f, tm_zip *tmzip, uLong *dt);

//path: utf8 path
CFileZipper& AddFile(const char* input_path, const char* inzip_path = "");
CFileZipper& AddDir(const char* input_dir, const char* temp_dir = NULL);

//output_path :utf8 path
bool ToZip(const char* output_path);

private:
std::map<std::string, std::string> files_;

};

#endif

 

cpp文件:

#include "FileZipper.h"
#include "tps\dirent.h"
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _WIN32
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>

#include <direct.h>
#include <io.h>

#ifdef _WIN32
#define USEWIN32IOAPI
#include "iowin32.h"
#endif

#define WRITEBUFFERSIZE (16384)
#define MAXFILENAME (256)


CFileZipper::CFileZipper()
{

}

CFileZipper::~CFileZipper()
{

}

int CFileZipper::isLargeFile(std::string filename)
{
int largeFile = 0;
ZPOS64_T pos = 0;
FILE* pFile = NULL;
//pFile = fopen64(filename.c_str(), "rb");
fopen_s(&pFile, filename.c_str(), "rb");

if (pFile != NULL)
{
int n = fseeko64(pFile, 0, SEEK_END);
pos = ftello64(pFile);

printf("File : %s is %lld bytes\n", filename.c_str(), pos);

if (pos >= 0xffffffff)
largeFile = 1;

fclose(pFile);
}

return largeFile;
}

uLong CFileZipper::filetime(const char* f, tm_zip *tmzip, uLong *dt)
{
int ret = 0;
{
FILETIME ftLocal;
HANDLE hFind;
WIN32_FIND_DATAA ff32;

hFind = FindFirstFileA(f, &ff32);
if (hFind != INVALID_HANDLE_VALUE)
{
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftLocal);
FileTimeToDosDateTime(&ftLocal, ((LPWORD)dt) + 1, ((LPWORD)dt) + 0);
FindClose(hFind);
ret = 1;
}
}
return ret;
}

int CFileZipper::ZipFiles(std::string &zipFileName, std::vector<std::string> files, bool bAppendFile, int nCompressLevel)
{
int size_buf = WRITEBUFFERSIZE;
void* buf = NULL;
buf = (void*)malloc(size_buf);

if (buf == NULL)
{
printf("Error allocating memory\n");
return ZIP_INTERNALERROR;
}

zipFile zf;
int err, errclose;
zlib_filefunc64_def ffunc;
fill_win32_filefunc64A(&ffunc);
zf = zipOpen2_64(zipFileName.c_str(), (bAppendFile) ? 2 : 0, NULL, &ffunc);

if (zf == NULL)
{
printf("error opening %s\n", zipFileName.c_str());
err = ZIP_ERRNO;
}
else
{
printf("creating %s\n", zipFileName.c_str());
err = ZIP_OK;
}

int i = 0;
for (; i < files.size() && (err == ZIP_OK); i++)
{
FILE* fin = NULL;
int size_read;
std::string filenameinzip = files[i];
std::string savefilenameinzip;
zip_fileinfo zi;
unsigned long crcFile = 0;
int zip64 = 0;

zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
zi.dosDate = 0;
zi.internal_fa = 0;
zi.external_fa = 0;
filetime(filenameinzip.c_str(), &zi.tmz_date, &zi.dosDate);

zip64 = isLargeFile(filenameinzip);

savefilenameinzip = filenameinzip.substr((filenameinzip.rfind(‘\\‘) + 1));

err = zipOpenNewFileInZip3_64(zf, savefilenameinzip.c_str(), &zi,
NULL, 0, NULL, 0, NULL /* comment*/,
(nCompressLevel != 0) ? Z_DEFLATED : 0,
nCompressLevel, 0,
/* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
NULL, crcFile, zip64);

if (err != ZIP_OK)
printf("error in opening %s in zipfile\n", filenameinzip.c_str());
else
{
//fin = fopen64(filenameinzip.c_str(), "rb");
fopen_s(&fin, filenameinzip.c_str(), "rb");
if (fin == NULL)
{
err = ZIP_ERRNO;
printf("error in opening %s for reading\n", filenameinzip.c_str());
}
}

if (err == ZIP_OK)
{
do
{
err = ZIP_OK;
size_read = (int)fread(buf, 1, size_buf, fin);
if (size_read < size_buf)
if (feof(fin) == 0)
{
printf("error in reading %s\n", filenameinzip.c_str());
err = ZIP_ERRNO;
}

if (size_read > 0)
{
err = zipWriteInFileInZip(zf, buf, size_read);
if (err < 0)
{
printf("error in writing %s in the zipfile\n",
filenameinzip.c_str());
}

}
} while ((err == ZIP_OK) && (size_read > 0));
}

if (fin)
fclose(fin);

if (err < 0)
err = ZIP_ERRNO;
else
{
err = zipCloseFileInZip(zf);
if (err != ZIP_OK)
printf("error in closing %s in the zipfile\n",
filenameinzip.c_str());
}
}

errclose = zipClose(zf, NULL);
if (errclose != ZIP_OK)
printf("error in closing %s\n", zipFileName.c_str());

if (buf != NULL)
free(buf);

return err;
}

 

void CFileZipper::ZipFilesFromFold(const std::string &zipFilepath, std::string &foldpath)
{

CFileZipper opera;
opera.AddDir(foldpath.c_str());
opera.ToZip(zipFilepath.c_str());
}

void CFileZipper::ZipFilesFromFold(const std::string &zipFilepath, std::vector<std::string>& filevecs)
{
CFileZipper opera;
for (int i=0; i<filevecs.size();++i)
{
opera.AddFile(filevecs[i].c_str());
}
opera.ToZip(zipFilepath.c_str());
}

#ifdef _WIN32

char* Utf8ToAnsi(const char* utf8)
{
// 先转换为UNICODE
int dwUnicodeLen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
if (!dwUnicodeLen)
{
return strdup(utf8);
}
size_t num = dwUnicodeLen * sizeof(wchar_t);
wchar_t *pwText = (wchar_t*)malloc(num + 2);
memset(pwText, 0, num + 2);
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, pwText, dwUnicodeLen);

// 再转换为ANSI
int len;
len = WideCharToMultiByte(CP_ACP, 0, pwText, -1, NULL, 0, NULL, NULL);
char *szANSI = (char*)malloc(len + 1);
memset(szANSI, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, pwText, -1, szANSI, len, NULL, NULL);

free(pwText);
return (char*)szANSI;
}

wchar_t* QXUtf82Unicode(const char* utf)
{
if (!utf || !strlen(utf))
{
return NULL;
}
int dwUnicodeLen = MultiByteToWideChar(CP_UTF8, 0, utf, -1, NULL, 0);
size_t num = dwUnicodeLen * sizeof(wchar_t);
wchar_t *pwText = (wchar_t*)malloc(num);
memset(pwText, 0, num);
MultiByteToWideChar(CP_UTF8, 0, utf, -1, pwText, dwUnicodeLen);
return pwText;
}

char* QXUnicode2Utf8(const wchar_t* unicode)
{
if (unicode == NULL)
{
return strdup("\0");
}

int len;
len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
char *szUtf8 = (char*)malloc(len + 1);
memset(szUtf8, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL, NULL);
return szUtf8;
}

FILE* ZipFopen(const char* path, const char* mode)
{
wchar_t* path_u = QXUtf82Unicode(path);
wchar_t* mode_u = QXUtf82Unicode(mode);
FILE* file = _wfopen(path_u, mode_u);
free(path_u);
free(mode_u);
return file;
}

/* name of file to get info on */
/* return value: access, modific. and creation times */
/* dostime */
uLong filetime(const char* f, tm_zip *tmzip, uLong *dt)
{
int ret = 0;
{
FILETIME ftLocal;
HANDLE hFind;
WIN32_FIND_DATA ff32;
wchar_t *unicode = QXUtf82Unicode(f);
hFind = FindFirstFile(unicode, &ff32);
if (hFind != INVALID_HANDLE_VALUE)
{
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftLocal);
FileTimeToDosDateTime(&ftLocal, ((LPWORD)dt) + 1, ((LPWORD)dt) + 0);
FindClose(hFind);
ret = 1;
}
free(unicode);
}
return ret;
}
#else
#define ZipFopen fopen;
#endif

CFileZipper& CFileZipper::AddFile(const char* input_path, const char* inzip_path)
{
files_[input_path] = inzip_path;
return *this;
}

CFileZipper& CFileZipper::AddDir(const char* input_dir, const char* temp_dir) {
WIN32_FIND_DATA findFileData;
auto input_dirw = QXUtf82Unicode(input_dir);

std::wstring path(input_dirw);
auto pos = path.at(path.size() - 1);
if (pos != L‘\\‘ && pos != L‘/‘) {
path.append(L"/");
}
HANDLE hFind = ::FindFirstFile((path + L"*").c_str(), &findFileData);
size_t file_name_len = 0;
if (hFind == INVALID_HANDLE_VALUE) {
free(input_dirw);
return *this;
}
else {

if (!temp_dir) {
temp_dir = input_dir;
}
std::string temp_dir2(temp_dir);
pos = temp_dir2.at(temp_dir2.size() - 1);
if (pos != ‘\\‘ && pos != ‘/‘) {
temp_dir2.append("/");
}

while (FindNextFile(hFind, &findFileData)) {

if (!wcscmp(findFileData.cFileName, L".") || !wcscmp(findFileData.cFileName, L".."))
continue;

std::wstring path1(path);
path1.append(findFileData.cFileName);
char* path_utf8 = QXUnicode2Utf8(path1.c_str());
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
AddDir(path_utf8, temp_dir);
}
else {
AddFile(path_utf8, path_utf8 + strlen(temp_dir2.c_str()));
}
free(path_utf8);
}
FindClose(hFind);
}
free(input_dirw);
}

bool CFileZipper::ToZip(const char* output_path)
{
int err = 0;
zipFile zf;
int errclose;
int opt_compress_level = Z_DEFAULT_COMPRESSION;
#ifdef USEWIN32IOAPI
zlib_filefunc64_def ffunc;
fill_win32_filefunc64W(&ffunc);
wchar_t* temp_path = QXUtf82Unicode(output_path);
zf = zipOpen2_64(temp_path, APPEND_STATUS_CREATE, NULL, &ffunc);
free(temp_path);
#else
zf = zipOpen64(output_path, APPEND_STATUS_CREATE);
#endif

if (zf == NULL)
{
printf("error opening %s\n", output_path);
err = ZIP_ERRNO;
return false;
}

void* buf = NULL;
int size_buf = WRITEBUFFERSIZE;
buf = (void*)malloc(size_buf);
for (auto ite = files_.begin(); ite != files_.end(); ++ite)
{
FILE * fin;
int size_read;
const char* filenameinzip = ite->first.c_str();
const char *savefilenameinzip = ite->second.c_str();
zip_fileinfo zi;
unsigned long crcFile = 0;
int zip64 = 0;

zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
zi.dosDate = 0;
zi.internal_fa = 0;
zi.external_fa = 0;
filetime(filenameinzip, &zi.tmz_date, &zi.dosDate);

const char* pos = NULL;
if (!strlen(savefilenameinzip)) {
savefilenameinzip = filenameinzip;
if ((pos = strrchr(savefilenameinzip, ‘\\‘))
|| (pos = strrchr(savefilenameinzip, ‘/‘))) {
pos++;
}
else {
pos = savefilenameinzip;
}
}
else {
pos = savefilenameinzip;
}

// 这个版本不支持UTF8字符串的正确存储,所以要转换为ANSI显示.
char* pos_ansi = Utf8ToAnsi(pos);
err = zipOpenNewFileInZip3_64(zf, pos_ansi, &zi,
NULL, 0, NULL, 0, NULL,
(opt_compress_level != 0) ? Z_DEFLATED : 0,
opt_compress_level, 0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
NULL, crcFile, zip64);
free(pos_ansi);

if (err != ZIP_OK)
{
printf("error in opening %s in zipfile\n", pos);
}
else
{
fin = ZipFopen(filenameinzip, "rb");
if (fin == NULL)
{
err = ZIP_ERRNO;
printf("error in opening %s for reading\n", filenameinzip);
}
}

if (err == ZIP_OK)
do
{
err = ZIP_OK;
size_read = (int)fread(buf, 1, size_buf, fin);
if (size_read < size_buf)
{
if (feof(fin) == 0)
{
printf("error in reading %s\n", filenameinzip);
err = ZIP_ERRNO;
}
}
if (size_read > 0)
{
err = zipWriteInFileInZip(zf, buf, size_read);
if (err < 0)
{
printf("error in writing %s in the zipfile\n",
filenameinzip);
}
}
} while ((err == ZIP_OK) && (size_read > 0));

if (fin)
{
fclose(fin);
}

if (err < 0)
{
err = ZIP_ERRNO;
}
else
{
err = zipCloseFileInZip(zf);
if (err != ZIP_OK)
{
printf("error in closing %s in the zipfile\n", filenameinzip);
}

}
}
errclose = zipClose(zf, NULL);
if (errclose != ZIP_OK)
{
printf("error in closing %s\n", output_path);
return false;
}
return true;
}

 

test:

CFileZipper opera;
std::string zipFileName = "D:\\ziptext2.zip";
std::string foldpath = "D:\\opt";
opera.ZipFilesFromFold(zipFileName, foldpath);

std::vector<std::string> filevecs;
filevecs.push_back("D:\\opt\\test1.bmp");
filevecs.push_back("D:\\opt\\test2.bmp");
opera.ZipFilesFromFold("D:\\ziptext1.zip", filevecs);

文件压缩,文件夹压缩

标签:push   dcl   osi   creation   ==   har   void   ror   off   

原文地址:https://www.cnblogs.com/Pond-ZZC/p/12918836.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!