怎样将c语言程序打包,C语言打包与解包程序.doc

#include typedef unsigned int uint;

typedef unsigned char byte;

// 包文件中最大可容纳的文件个数

#define MAX_FILE_COUNT 10

// 全局包文件指针

FILE* g_pMasFile = NULL;

// 资源包文件头结构

typedef struct SMaseFileHeader

{

uint uFileFlag; // 包文件头标记: 'MASE'

uint uFileCount; // 包内文件个数

uint uFileListOfs; // 文件列表偏移

uint uMaxFileCount; // 最大子文件个数

uint uFileSize; // 包文件的大小

}MaseHeader;

// 包内文件信息结构

typedef struct SFilesMessage

{

uint uFileOfs; // 本文件在包内的偏移

uint uFileSize; // 本文件的大小

char szFileName[260]; // 本文件的路径

}FilesMsg;

// 打开包文件

int OpenMasFile(const char* path, const byte onlyOpen)

{

uint uWriteCount; // 写入文件信息次数

byte bIsNew = 0; // 是否新建的

MaseHeader header; // 文件头结构定义

FilesMsg msg; // 文件信息结构定义

g_pMasFile = fopen(path, "rb"); // 用来判断是否存在

if (g_pMasFile == NULL)

{

if (onlyOpen == 1) // 只打开不新建

return -1;

bIsNew = 1;

g_pMasFile = fopen(path, "wb");

if (g_pMasFile == NULL)

return -1;

}

//先关闭,然后在用"rb+"方式打开 二进制读写打开文件

fclose( g_pMasFile );

g_pMasFile = fopen(path, "rb+");

if (g_pMasFile == NULL)

return -1;

if(bIsNew == 1)// 新建的文件

{

header.uFileFlag = 'ESAM';

header.uFileCount = 0;

header.uFileListOfs = sizeof(MaseHeader); //紧跟着就是文件列表

header.uMaxFileCount = MAX_FILE_COUNT;

header.uFileSize = sizeof(MaseHeader)

+ (MAX_FILE_COUNT * sizeof(FilesMsg));

//写入头信息

fwrite(&header, sizeof(MaseHeader), 1, g_pMasFile);

memset(&msg, 0, sizeof(FilesMsg));

uWriteCount = MAX_FILE_COUNT;

//写入文件列表用0占位

while(uWriteCount--)

fwrite(&msg, sizeof(FilesMsg), 1, g_pMasFile);

}

else//文件存在

{

//则读取头文件信息

fread(&header, sizeof(MaseHeader), 1, g_pMasFile);

}

//检查文件头标记

if (header.uFileFlag != 'ESAM')

{

fclose(g_pMasFile);

printf("文件头标记不对,错误!\n");

return -1;

}

//检查数据是否完整

if (header.uMaxFileCount != MAX_FILE_COUNT)

{

fclose(g_pMasFile);

printf("数据不完整,错误!\n");

return -1;

}

return 0;

}

//写文件到包里

int WriteFileToPak(const char* path)

{

FilesMsg fileMsg; //此文件的文件信息结构

MaseHeader header; //包文件头结构定义

uint uFileSize;

uint uFileListEndOfs;

byte* pBuff;

FILE* pFile = NULL;

if (g_pMasFile == NULL)

return -1;

memset(&fileMsg, 0, sizeof(FilesMsg));

fseek(g_pMasFile, 0, SEEK_SET); //定位到文件头,读取头文件信息

//则读取头文件信息

fread(&header,sizeof(MaseHeader), 1, g_pMasFile);

uFileListEndOfs = header.uFileCount * sizeof(FilesMsg) + header.uFileListOfs;

pFile = fopen(path, "rb");

if(pFile == NULL)

return -1;

fseek(pFile, 0, SEEK_END);

uFileSize = ftell(pFile);

fseek(pFile, 0, SEEK_SET);

//文件名长度不能超过260

strcpy(fileMsg.szFileName,path);

fileMsg.uFileOfs = header.uFileSize;

fileMsg.uFileSize = uFileSize;

// 写入文件信息

// 将文件指针定位到uFileListEndOfs处,以便写入新的文件信息结构

fseek(g_pMasFile, uFileListEndOfs, SEEK_SET);

fwrite(&fileMsg,sizeof(FilesMsg),1,g_pMasFile);

// 申请空间

pBuff = (byte*)malloc(uFileSize);

fread(pBuff,uFileSize,1,pFile);

// 写数据到包文件里

fseek(g_pMasFile,header.uFileSize,SEEK_SET);

fwrite(pBuff, uFileSize, 1, g_pMasFile);

// 释放内存

free(pBuff);

//重新填充header

header.uFileCount += 1;

header.uFileSize += uFileSize;

fseek( g_pMasFile,0,SEEK_SET);

// 重新写入包文件头

fwrite(&header,sizeof(MaseHeader),1,g_pMasFile);

return 0;

}

//从包文件里读数据

int ReadFileFromPak(const FilesMsg msg, byte* _dst)

{

if ( g_pMasFile == NULL )

return -1;

fseek(g_pMasFile, msg.uFileOfs,SEEK_SET);

fread(_dst, msg.uFileSize, 1, g_pMasFile);

return 0;

}

//获取包中某个文件的信息

int GetFileMessage( const char* path, FilesMsg* msg)

{

FilesMsg fileMsg; // 此文件的文件信息结构

MaseHeader header; // 包头结构

uint uFileCount; // 文件个数

if ( g_pMasFile == NULL || msg == NULL )

return -1;

// 则读取头文件信息

fseek(g_pMasFile, 0, SEEK_SET);

fread(&header, sizeof(MaseHeader), 1, g_pMasFile);

uFileCount = header.uFileCount;

while (uFileCount--)

{

fread(&fileMsg, sizeof(FilesMsg), 1,g_pMasFile);

// 判断是否是要获取的文件

if (stricmp(fileMsg.szFileName, path) == 0 )

{

*msg = fileMsg;

return 0;

}

}

return -1;

}

// 关闭包文件

int CloseMasFile( void )

{

if ( g_pMasFile == NULL )

return -1;

fclose( g_pMasFile );

g_pMasFile = NULL;

return 0;

}

//这是打包主函数

int main( void )

{

int ret;

ret = OpenMasFile( "E:\\PhotoPak.bin",0);

if ( ret == -1 )

goto __exit;

WriteFileToPak( "E:\\珍贵.jpg" );

WriteFileToPak( "E:\\123.docx" );

WriteFileToPak( "E:\\456.txt" );

__exit:

CloseMasFile();

return 0;

}

//查看打包中的文件,并且可以解包查看

int main( void )

{

byte* pBuff;

FILE* pOutFile;

FilesMsg getFileMsg;

int ret;

ret = OpenMasFile("E:\\PhotoPak.bin", 1);

if (ret == -1)

goto __exit;

ret = GetFileMessage("E:\\123.docx", &getFileMsg);

if(ret == -1)

goto __exit;

pBuff = (byte*)malloc(getFileMsg.uFileSize);

ret = ReadFileFromPak(getFileMsg, pBuff);

if(ret == -1)

goto __exit_free;

pOutFile = fopen("E:\\123_out.docx", "wb"); // 注意使用的是二进制模式

if(ret == -1)

goto __exit_free;

fwrite( pBuff, getFileMsg.uFileSize, 1, pOutFile );

fclose( pOutFile );

__exit_free:

free( pBuff );

__exit:

CloseMasFile();

return 0;

}

参数

源文件  要装入到编译程序中的文件的路径.文件名必须是字符串,不能是任何变量. 它可以是一个相对路径(使用 .\ 或者 ..\ 等在路径中)

目标路径 结尾带有反斜线符号的目标路径,脚本程序运行时将把嵌入文件解压到此位置.此参数接受变量.

标志 [可选参数] 此标志参数用以决定是否覆盖已存在的文件:

0 = (默认)不覆盖已存在的文件

1 = 覆盖已存在的文件

返回值

成功: 返回值为1.

失败: 返回值为0.

注意/说明

FileInstall 函数的用途是装入文件到编译后的 AutoIt 脚本程序中.这些内嵌的文件将在编译好的脚本程序运行时被"解压"出来.这里要提醒一下的就是装入某些文件如图片文件等可能会导致编译后的脚本程序大小剧增.

源文件(来源文件)参数只接受字符串而不接受变量,计算式或者函数CALL,以便编译器能正确取得文件名并装入文件.

源文件参数不能含有通配符.

若在未编译的脚本中使用此函数则程序将执行一次文件复制操作(这样是为了方便进行预编译测试).

装入的文件将保持原本的创建时间/修改时间等时间戳信息.

目标目录必须存在才能调用此函数,不然FileInstall将会失败, 返回 0 并不会创建文件和路径. 参考 DirCreate() 函数关于创建目录路径.

已存在的文件属性可能导致函数覆盖失败.请使用 FileDelete() 或者 FileSetAttrib() 确保文件能够被覆盖.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值