gpt4 book ai didi

c++ - 使用 minizip 从内存缓冲区打开文件

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:30:11 25 4
gpt4 key购买 nike

我正在搜索如何使用 minizip 从内存缓冲区打开存档。

我从他们的页面 http://www.winimage.com/zLibDll/minizip.html 找到了 ioapi_mem_c.zip .

我不明白如何使用它。有人可以给我举个例子吗?

最佳答案

我解决了解压问题:我在 unzip.c 中添加了这个函数

extern unzFile ZEXPORT unzOpenBuffer (const  void* buffer, uLong size)
{
char path[16] = {0};
zlib_filefunc64_32_def memory_file;
uLong base = (uLong)buffer;

sprintf(path, "%x+%x", base, size);

fill_memory_filefunc64_32(&memory_file);
return unzOpenInternal(path, &memory_file, 0);
}

并对ioapi_mem.c做了一些修改:

void fill_memory_filefunc64_32 (pzlib_filefunc_def)
zlib_filefunc64_32_def* pzlib_filefunc_def;
{
pzlib_filefunc_def->zopen32_file = fopen_mem_func;
pzlib_filefunc_def->zfile_func64.zopen64_file = fopen_mem_func;
pzlib_filefunc_def->zfile_func64.zread_file = fread_mem_func;
pzlib_filefunc_def->zfile_func64.zwrite_file = fwrite_mem_func;
pzlib_filefunc_def->ztell32_file = ftell_mem_func;
pzlib_filefunc_def->zseek32_file = fseek_mem_func;
pzlib_filefunc_def->zfile_func64.zseek64_file = NULL;
pzlib_filefunc_def->zfile_func64.zclose_file = fclose_mem_func;
pzlib_filefunc_def->zfile_func64.zerror_file = ferror_mem_func;
pzlib_filefunc_def->zfile_func64.opaque = NULL;
}

我希望这能帮助遇到同样问题的人。

下面是如何使用它的简单类实现:

 void ZipArchiveImpl::OpenArchive()
{
ASSERT(!mInited, "Already opened.");


if ((mFileMode == FM_READ))
{
if (mArchiveName.size() == 0)
{


u32 sz = mFile->GetFileSize();
mUnzBlock.Resize(sz);
mFile->SetPosition(0);
mFile->Read(mUnzBlock.Data(), mUnzBlock.GetSizeInBytes());

mUnzHandle = unzOpenBuffer(mUnzBlock.Data(), mUnzBlock.GetSizeInBytes());

}
else
{
mUnzHandle = unzOpen(mArchiveName.c_str());
}

if (!mUnzHandle) return;
FillMap();
}

else if (mFileMode == FM_WRITE)
{
ASSERT0(mArchiveName.size());
mZipHandle = zipOpen(mArchiveName.c_str(), 0);

if (!mZipHandle) return;
}



mInited = true;
}

IFile* ZipArchiveImpl::OpenRead(const std::string& name)
{
if (IsExist(name))
{

ZipFileInfo info = mFileMap.find(name)->second;

MemoryBlock block(1);
block.Resize(info.uncompressedSize);

int res = unzGoToFilePos(mUnzHandle, &info.filePosInfo);
if (UNZ_OK != res)
{
return false;
}

// open the current file with optional password
if (mArchivePassword != "")
{
res = unzOpenCurrentFilePassword(info.zipFileHandle, mArchivePassword.c_str());
}
else
{
res = unzOpenCurrentFile(info.zipFileHandle);
}
if (UNZ_OK != res)
{
return false;
}

// read uncompressed data
int readResult = unzReadCurrentFile(info.zipFileHandle, block.Data(), info.uncompressedSize);

// close the file
res = unzCloseCurrentFile(info.zipFileHandle);
if (UNZ_OK != res)
{
return false;
}

if (info.uncompressedSize == readResult)
{
return ROBE_NEW MemoryFile(block.Data(), info.uncompressedSize);
}
else
{
return NULL;
}
}
else
{
return NULL;
}
}

IFile* ZipArchiveImpl::OpenRead(u32 id)
{
ASSERT0(mFileNames.size() > id);
if (IsExist(mFileNames[id]))
{
return OpenRead(mFileNames[id]);
}
else
{
return NULL;
}
}

void ZipArchiveImpl::FillMap()
{
s32 walkRes = unzGoToFirstFile(mUnzHandle);
unz_file_info info;
while (UNZ_OK == walkRes)
{

// get info about current file
char currentFileName[512];
s32 fileInfoRes = unzGetCurrentFileInfo(mUnzHandle, &info, currentFileName, sizeof(currentFileName), 0, 0, 0, 0);

std::string name = std::string(currentFileName);
mFileNames.push_back(name);
InitInfo(name, &info);
walkRes = unzGoToNextFile(mUnzHandle);

}
OpenRead(0);

if (UNZ_END_OF_LIST_OF_FILE != walkRes)
{

}
}

void ZipArchiveImpl::InitInfo(const std::string& name, unz_file_info* info)
{
ZipFileInfo zfi;
mFileMap.insert(std::pair<std::string, ZipFileInfo>(name, zfi));
mFileMap[name].zipFileHandle = mUnzHandle;
int res = unzGetFilePos(mFileMap[name].zipFileHandle, &mFileMap[name].filePosInfo);

mFileMap[name].uncompressedSize = info->uncompressed_size;

char lastsymbol = name[name.size() - 1];
if (lastsymbol == '/' || lastsymbol == '\\')
{
mFileMap[name].type = ZFT_DIR;
}
else
{
mFileMap[name].type = ZFT_FILE;
}
}


ZipArchiveImpl::~ZipArchiveImpl()
{
if (mInited)
{
if (mUnzHandle) unzClose(mUnzHandle);
if (mZipHandle) zipClose(mZipHandle, 0);
}
}

bool ZipArchiveImpl::IsExist(const std::string& name)
{
return (mFileMap.find(name) != mFileMap.end());
}

void ZipArchiveImpl::SaveFileToZip(const std::string& path, IFile* file)
{
const u32 DefaultFileAttribute = 32;


MemoryBlock block(1);
block.Resize(file->GetFileSize());
file->Read(block.Data(), block.GetSizeInBytes());

zip_fileinfo zinfo;

memset(&zinfo, 0, sizeof(zinfo));

zinfo.internal_fa = 0;
zinfo.external_fa = DefaultFileAttribute;

::boost::posix_time::ptime pt = ::boost::posix_time::from_time_t(time(0));
std::tm ptm = ::boost::posix_time::to_tm(pt);

zinfo.dosDate = 0;
zinfo.tmz_date.tm_year = ptm.tm_year;
zinfo.tmz_date.tm_mon = ptm.tm_mon;
zinfo.tmz_date.tm_mday = ptm.tm_mday;
zinfo.tmz_date.tm_hour = ptm.tm_hour;
zinfo.tmz_date.tm_min = ptm.tm_min;
zinfo.tmz_date.tm_sec = ptm.tm_sec;

zipOpenNewFileInZip(mZipHandle, path.c_str(), &zinfo, 0, 0, 0, 0, 0, Z_DEFLATED, Z_BEST_SPEED);
zipWriteInFileInZip(mZipHandle, block.Data(), block.GetSizeInBytes());
zipCloseFileInZip(mZipHandle);
}

unsigned long ZipArchiveImpl::GetFileAttributes(const std::string& filePath)
{
unsigned long attrib = 0;
#ifdef WIN32
attrib = ::GetFileAttributes(filePath.c_str());
#else
struct stat path_stat;
if (::stat(filePath.c_str(), &path_stat) == 0)
{
attrib = path_stat.st_mode;
}
#endif
return attrib;
}

关于c++ - 使用 minizip 从内存缓冲区打开文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16274100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com