准备 使用 的 文件 格式

本文介绍了一个使用Boost库中的zlib组件来压缩文件的应用程序。该程序将多个文件打包成一个压缩文件,并记录每个文件的原始大小、压缩后大小及其在压缩包中的位置。此外,还使用CRC校验来确保数据的完整性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// testZlib.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

//#define BOOST_IOSTREAMS_SOURCE
#include <boost/static_assert.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/counter.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/crc.hpp>
//#include <boost/../libs/iostreams/src/zlib.cpp>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
typedef std::vector<char>	DataStream;

using namespace std;
const DWORD dwVersion = MAKELONG(MAKEWORD('z', 'y'), MAKEWORD('z', 'f'));
struct PacketFileHeader
{
	DWORD	version;
	DWORD	dwFileHeaderPos;		//FileHeader 开始的偏移位置
	DWORD	dwTotalFile;			//保存了多少个文件.在文件头之后,都是每一个文件的内容,文件结尾保存文件的名字和原来大小及位置
};
const int packetFileHeaderLenght = sizeof(PacketFileHeader);

struct FileHeader
{
	char	fileName[32];
	DWORD	dwOriginFileSize;			//原来文件的大小
	DWORD	dwFileOffset;				//在压缩包中文件的偏移 
	DWORD	dwFileSize;					//压缩后的大小。
	DWORD	crc;

};
const int fileHeaderSize = sizeof(FileHeader);

const std::string strDir("E:\\QQ资源\\Data\\Head\\");
bool changeName(const char* src, const char* dst)
{
	char buf[1024];
	_snprintf(buf, 1024, "rename %s%s %s", strDir.c_str(), src, dst);
	system(buf);
	return true;
}
class CPacketFileReader
{
	std::string			m_strFilename;
	std::ifstream		m_in;
	PacketFileHeader	m_packetFileHeader;
public:
	CPacketFileReader() { }
	~CPacketFileReader() { if(m_in) m_in.close(); }
	bool OpenPacket(const char* strPacketFileName)
	{
		m_strFilename = strPacketFileName;
		if (!m_in.open(m_strFilename))
		{
			return false;
		}
		m_in.read((const char*)&m_packetFileHeader, sizeof(m_packetFileHeader))
	}
};
bool PacketAFile(const char* fileName, DataStream& ds, FileHeader& fh)
{
	memset(&fh, 0, sizeof(FileHeader));
	strcpy(fh.fileName, fileName);
	std::string strFullPathName = strDir;
	strFullPathName += fileName;
	HANDLE hFile = CreateFileA(strFullPathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return false;
	}
	DWORD dwHigh = 0;
	DWORD dwFileSize = GetFileSize(hFile, &dwHigh);
	if (dwHigh != 0)
	{
		CloseHandle(hFile);
		return false;
	}
	char *pBuffer = new char[dwFileSize];
	DWORD dwFileRead = 0;
	if(!ReadFile(hFile, pBuffer, dwFileSize, &dwFileRead, NULL))
	{
		CloseHandle(hFile);
		return false;
	}
	if (dwFileRead != dwFileSize)
	{
		CloseHandle(hFile);
		return false;
	}
	CloseHandle(hFile);
	ds.resize(0);
	boost::iostreams::copy(boost::make_iterator_range(pBuffer, pBuffer + dwFileRead),
		boost::iostreams::filtering_ostream(boost::iostreams::zlib_compressor() | boost::iostreams::back_inserter(ds)));

	fh.dwOriginFileSize = dwFileSize;
	fh.dwFileSize = ds.size();

	boost::crc_32_type crc;
	crc.process_bytes(&ds[0], ds.size());
	fh.crc = crc.checksum();
	//偏址由调用者填写。
	return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
	//string str("12345678 12345678");
	//string zip_str, unzip_str;

	//boost::iostreams::copy(boost::make_iterator_range(str),
	//	boost::iostreams::filtering_ostream(boost::iostreams::zlib_compressor() | back_inserter(zip_str)));

	//boost::iostreams::copy(boost::make_iterator_range(zip_str),
	//	boost::iostreams::filtering_ostream(boost::iostreams::zlib_decompressor() | back_inserter(unzip_str)));
	char tmpBuf[32];
	int j = 123;
	char tmpBuf2[32];
	//for (int i = 257; i >= (257-3); --i)
	//{
	//	_snprintf(tmpBuf, 32, "%d.png", i);
	//	_snprintf(tmpBuf2, 32, "%d.png", j);
	//	changeName(tmpBuf, tmpBuf2);

	//	_snprintf(tmpBuf, 32, "%d_100.gif", i);
	//	_snprintf(tmpBuf2, 32, "%d_100.gif", j);
	//	changeName(tmpBuf, tmpBuf2);

	//	_snprintf(tmpBuf, 32, "%d_16.bmp", i);
	//	_snprintf(tmpBuf2, 32, "%d_16.bmp", j++);
	//	changeName(tmpBuf, tmpBuf2);

	//}
	//return 0;
	std::ofstream out("d:\\res.dat", std::ios::binary);
	if (!out)
	{
		std::cout << "open file failed." << std::endl;
		return -1;
	}
	PacketFileHeader pfh;
	out.write((const char*)&pfh, packetFileHeaderLenght); //先写头。
	int offset = packetFileHeaderLenght;
	DataStream ds;
	std::vector<FileHeader> fileHeaderArray;
	FileHeader fh;
	for (int i = 1; i <= 254; ++i)
	{
		_snprintf(tmpBuf, 32, "%d.png", i);
		if (PacketAFile(tmpBuf, ds, fh)) //打包png
		{
			fh.dwFileOffset = offset;
			offset += fh.dwFileSize;
			out.write(&ds[0], ds.size());
			fileHeaderArray.push_back(fh);
		}
		else 
		{
			std::cout << "error:" << tmpBuf << std::endl;
			return -1;
		}

		//_snprintf(tmpBuf, 32, "%d_100.gif", i);
		//if (PacketAFile(tmpBuf, ds, fh))	//打包Gif
		//{
		//	fh.dwFileOffset = offset;
		//	offset += fh.dwFileSize;
		//	out.write(&ds[0], ds.size());
		//	fileHeaderArray.push_back(fh);
		//}
		//else 
		//{
		//	std::cout << "error:" << tmpBuf << std::endl;
		//	return -1;
		//}
		_snprintf(tmpBuf, 32, "%d_16.bmp", i);
		if (PacketAFile(tmpBuf, ds, fh))	//打包bmp
		{
			fh.dwFileOffset = offset;
			offset += fh.dwFileSize;
			out.write(&ds[0], ds.size());
			fileHeaderArray.push_back(fh);
		}
		else 
		{
			std::cout << "error:" << tmpBuf << std::endl;
			return -1;
		}

	}
	//写每个文件的文件头
	for (int i = 0; i < fileHeaderArray.size(); ++i)
	{
		out.write((const char*)&fileHeaderArray[i], fileHeaderSize);
	}
	pfh.version = dwVersion;
	pfh.dwTotalFile = fileHeaderArray.size();
	pfh.dwFileHeaderPos = offset + packetFileHeaderLenght;
	out.seekp(0);
	out.write((const char*)&pfh, packetFileHeaderLenght);
	out.close();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值