数据流小说带点h_上午写了两个类,实现了自定义资源文件,数据流的存取,一个字爽...

精确的概括是:

按名称从资源文件里面读和写二进制raw数据(raw在文件里面是按zlib压缩的形式存储的)

这样我就可以把一些文件资源用对应的api读入到内存的buffer中去,然后通过我的资源库压缩buffer再写入到资源文件里面去,下次真正调用的时候读出来解压还原到内存的buffer里面去使用。

下面要做的事情就是把游戏里面所有的资源文件都打包了。

只是目前还没有加上加密的算法

//看一段测试代码

void testFilestream()

{

FileStream filestream;

filestream.Open("aaa.bin", "r+");

char *p=0;

DWORD ln = 0;

char *src = "hello,a big boy";

filestream.Write("xxx.xxx", src, strlen(src));

filestream.Read("xxx.xxx", (void **)&p, ln);

printf("%s :%d\r\n", p, ln);

DELS(p);

filestream.Close();

}

结果:

hello,a big boy :15

请按任意键继续. . .

源码如下:

/************************************************************************/

/* 按命名从资源文件里面读和写raw数据(raw在文件里面是按zlib压缩的形式存储的)

/************************************************************************/

#pragma once

#ifndef FILESTREAM_H

#define FILESTREAM_H

#include

#include

#include

#include

#include "../include/zlib.h"

#pragma comment(lib,"../lib/zdll.lib")

namespace LK3D

{

class FileStream;

//

// 文件或数据流(不支持同时读写多个数据区,只能一次对FileStream的一个数据区进行读写操作)

class FileDataStreamBuffer

{

private:

DWORD  zipbuflen;       //zip raw buffer len

void * zipbuf;          //zip raw buffer         压缩字节流

//按照buflen重新分配空间

void realloc();

DWORD  srcbuflen;       //source raw buffer len

std::string dataname;   //该数据流的名字

public:

DWORD GetSrcBufLen();

//构造

FileDataStreamBuffer(const char *dname);

//析构

~FileDataStreamBuffer();

//写字节,写之前一定要设定dataname

DWORD WriteBytes(const void *from,DWORD len);

//读字节,写之前一定要设定dataname

DWORD ReadBytes(void *to);

//debug

void DumpBuffer();

DWORD GetLen() const;   //总长度,是计算出来的

bool operator ==(const FileDataStreamBuffer &other) const;

friend class FileStream;

};

class FileStream

{

FILE *pFile;

private:

//写文件包,写之前一定要设定filebuf.dataname

DWORD Write(FileDataStreamBuffer& filebuf);

//读文件包,读之前一定要设定filebuf.dataname

DWORD Read(FileDataStreamBuffer& filebuf);

public:

FileStream(void);

~FileStream(void);

//打开一个文档

DWORD Open(const char* archive,const char *mode);

//写某个数据段落

DWORD Write(const char* dname, const void *from, DWORD len);

//读取某个数据段落

DWORD Read(const char* dname, void **to, DWORD &len);

//关闭文件流

void Close();

friend void testFileStream();

};

void testFileStream();

void testFileStream1();

}

#endif

//FileStream.cpp

#include "FileStream.h"

#ifndef DEL

#define DEL(p)  { if(p) { delete (p); (p) = NULL; } }

#endif

#ifndef DELS

#define DELS(p)  { if(p) { delete[] (p); (p) = NULL; } }

#endif

#ifndef RELEASE

#define RELEASE(p)  { if(p) { (p)->Release(); (p) = NULL; } }

#endif

using namespace LK3D;

FileDataStreamBuffer::FileDataStreamBuffer(const char *dname)

{

zipbuflen = 0;

zipbuf = 0;

srcbuflen = 0;

dataname = dname;

}

DWORD FileDataStreamBuffer::GetSrcBufLen()

{

return srcbuflen;

}

FileDataStreamBuffer::~FileDataStreamBuffer()

{

DELS(zipbuf);

}

void FileDataStreamBuffer::realloc()

{

DELS(zipbuf);

zipbuf = new char[zipbuflen];

}

bool FileDataStreamBuffer::operator ==(const FileDataStreamBuffer &other) const

{

return GetLen() == other.GetLen() &&

dataname == other.dataname &&

zipbuflen == other.zipbuflen &&

memcmp((const char *)zipbuf, (const char *)other.zipbuf, zipbuflen) == 0 &&

srcbuflen == other.srcbuflen;

}

DWORD FileDataStreamBuffer::GetLen() const

{

//     文件名长度占位  文件名长度               srcbuf长度占位  zipbuf长度占位  zipbuf长度

return sizeof(DWORD) + (DWORD)dataname.size() + sizeof(DWORD) + sizeof(DWORD) + zipbuflen;

}

//写字节

DWORD FileDataStreamBuffer::WriteBytes(const void *from,DWORD len)

{

if(dataname.empty())

return 0;    //还未给要写入的部分命名

if(!from)

return 0;

//记录原字节数据区的长度

srcbuflen = len;

//重新分配zipbuf的空间

//DELS(zipbuf);

zipbuflen =(DWORD)(len+ (len * 0.1) + 12); //这是个公式,官方网站上提供的,预留的最小的压缩空间的大小

realloc();

//压缩原数据到zipbuf中去

compress2((Bytef*)zipbuf,(uLongf*)&zipbuflen,(const Bytef*)from,(uLongf)srcbuflen, Z_DEFAULT_COMPRESSION);

return len;

}

//读字节

DWORD FileDataStreamBuffer::ReadBytes(void *to)

{

//if(dataname.empty())

//  return 0;    //还未给要读取的部分命名

if(!to)

return 0;

uncompress((Bytef*)to, (uLongf *)&srcbuflen, (const Bytef*)zipbuf, (uLong)zipbuflen);

return zipbuflen;

}

void FileDataStreamBuffer::DumpBuffer()

{

DWORD len = zipbuflen;

printf("Buffer: size=%d", len);

if (len > 0)

{

printf("  [ ");

const UCHAR* pBuf = (const UCHAR*) zipbuf;

for (DWORD i = 0; i < len; ++i)

printf("%02X ", pBuf[i]);

printf("]");

}

printf("\n");

}

FileStream::FileStream(void)

{

pFile = 0;

}

FileStream::~FileStream(void)

{

Close();

}

//打开一个文档

DWORD FileStream::Open(const char* archive,const char *mode)

{

pFile = fopen(archive, mode);

assert(pFile);

return 0;

}

//写文件包

DWORD FileStream::Write(FileDataStreamBuffer& filebuf)

{

if(filebuf.dataname.empty())

{

return 0; //指定要读取的数据区的名称

}

DWORD writebytes = 0;

//写入文件名的长度占位

DWORD filenamelen = (DWORD)filebuf.dataname.size();

writebytes+=(DWORD)(fwrite(&filenamelen, sizeof(DWORD), 1, pFile) * sizeof(DWORD));

//写入文件名

writebytes+=(DWORD)(fwrite(filebuf.dataname.c_str(), sizeof(char), filebuf.dataname.size(), pFile) * sizeof(char));

//写入srcbuf长度的占位

writebytes+=(DWORD)(fwrite(&filebuf.srcbuflen, sizeof(DWORD), 1, pFile) * sizeof(DWORD));

//写入zipbuf的长度占位

writebytes+=(DWORD)(fwrite(&filebuf.zipbuflen, sizeof(DWORD), 1, pFile) * sizeof(DWORD));

//写入zipbuf

writebytes+=(DWORD)(fwrite(filebuf.zipbuf, sizeof(char), filebuf.zipbuflen, pFile) * sizeof(char));

return writebytes;

}

//读文件包

DWORD FileStream::Read(FileDataStreamBuffer& filebuf)

{

if(filebuf.dataname.empty())

{

return 0; //指定要读取的数据区的名称

}

//从文件头开始

rewind(pFile);

char filename[100]; //文件名预留100应该足够了

ZeroMemory(filename, 100);

//实际读取的数量

DWORD readbytes = 0;

bool founded = false;

// bool bt = false;

// fseek(filebuf,1000, SEEK_CUR);

while(filebuf.dataname != filename)

{

//读入文件名长度的占位

DWORD filenamelen = 0;

readbytes += (DWORD)(fread(&filenamelen, sizeof(DWORD), 1, pFile) * sizeof(DWORD));

if(readbytes == 0)

break; //已经无法读取数据了,说明已经eof了

//读入文件名

readbytes += (DWORD)(fread(&filename, sizeof(char), filenamelen, pFile) * sizeof(char));

//读入srcbuf长度占位

readbytes += (DWORD)(fread(&filebuf.srcbuflen, sizeof(DWORD), 1, pFile) * sizeof(DWORD));

//读入zipbuf长度占位

readbytes += (DWORD)(fread(&filebuf.zipbuflen, sizeof(DWORD), 1, pFile) * sizeof(DWORD));

if(filebuf.dataname == filename)

{

//重新分配可以装载数据的空间

filebuf.realloc();

readbytes += (DWORD)(fread(filebuf.zipbuf, sizeof(char), filebuf.zipbuflen, pFile) * sizeof(char));

founded = true;

break;

}

else

{

readbytes = 0;  //重新计数

//不是要找的data直接后移filebuf.zipbuflen

fseek(pFile, filebuf.zipbuflen, SEEK_CUR);

filebuf.zipbuflen = 0; //读取的zipbuffer长度也清0,作废处理

filebuf.srcbuflen = 0; //读取的srcbuffer长度也清0,作废处理

}

ZeroMemory(filename, 100);

}

if(founded)

return readbytes; //返回实际读取的字节数

else

return 0;         //读取失败了

}

//关闭文件流

void FileStream::Close()

{

if(pFile)

{

fclose(pFile);

pFile = 0;

}

}

DWORD FileStream::Write(const char* dname, const void *from,DWORD len)

{

FileDataStreamBuffer streambuf(dname);

if(!streambuf.WriteBytes(from, len))

return 0;

return Write(streambuf);

}

DWORD FileStream::Read(const char* dname, void **to, DWORD &len)

{

FileDataStreamBuffer streambuf(dname);

if(Read(streambuf))

{

if(*to)

{

printf("warning, 销毁接收缓冲...");

DELS(*to)

}

len = streambuf.GetSrcBufLen();

*to = new char[len];

streambuf.ReadBytes(*to);

return len;

}

else

return 0;

}

void LK3D::testFileStream()

{

FileDataStreamBuffer f1("file1.txt");

char *str1 ="one 111";

f1.WriteBytes(str1, (DWORD)strlen(str1));

FileDataStreamBuffer f2("file2.txt");

char *str2 ="a111111111111111111b";

f2.WriteBytes(str2, (DWORD)strlen(str2));

FileStream stream;

//写

stream.Open("aaa.bin", "wb");

DWORD d1 = stream.Write(f1);

DWORD d2 = stream.Write(f2);

assert(d1 == f1.GetLen());

assert(d2 == f2.GetLen());

stream.Close();

f2.DumpBuffer();

//读

FileStream stream1;

stream1.Open("aaa.bin", "rb");

FileDataStreamBuffer val_bf("file2.txt");

DWORD vd2 = stream1.Read(val_bf);

stream1.Close();

val_bf.DumpBuffer();

if(vd2)

{

assert(vd2 == d2);

assert(f2 == val_bf);

char *c = new char[val_bf.GetSrcBufLen() +1];

ZeroMemory(c, val_bf.GetSrcBufLen() +1);

val_bf.ReadBytes(c);

printf("%s \r\n", c);

} else

{

printf("没找到数据\r\n");

}

}

void LK3D::testFileStream1()

{

FileStream filestream;

filestream.Open("aaa.bin", "r+");

char *p=0;

DWORD ln = 0;

char *src = "hello,a big boy";

filestream.Write("xxx.xxx", src, (DWORD)strlen(src));

filestream.Read("xxx.xxx", (void **)&p, ln);

printf("%s :%d\r\n", p, ln);

DELS(p);

filestream.Close();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值