lua版的存档未经压缩,尺寸比较大,文件分为多个,分享很不方便。
因为lua版中的存档代码很多地方是分开写的,如果直接在内存中压缩,程序要改的地方可能比较多。
那么我们可以增加两个压缩和解压缩的函数,在存档时先按照以前的方案写,然后压缩文件,再将未压缩的文件删除,读档时也类似。这样可以少改一些代码。
首先下载附件,里面是头文件和库文件,需要在visual studio里面配置好,这个就不细讲了。
要改的代码如下:
luafun.c增加这两个函数(请自己在jymain.h里添加声明,以及所需的头文件)。
- int Byte_unzip(lua_State *pL)
- {
- const char *filenamezip = lua_tostring(pL, 1);
- int n = lua_gettop(pL);
- int i;
- unzFile zip;
- zip = unzOpen(filenamezip);
- for (i = 2; i <= n; i++)
- {
- const char *filename = lua_tostring(pL, i);
- unz_file_info zi = { 0 };
- if (unzLocateFile(zip, filename, NULL) != UNZ_OK)
- {
- break;
- }
- char s[100];
- unzGetCurrentFileInfo(zip, &zi, s, 100, NULL, 0, NULL, 0);
- unzOpenCurrentFile(zip);
- FILE *fp;
- if ((fp = fopen(filename, "wb")) == NULL)
- {
- break;
- }
- void* buf = malloc(8192);
- int c = 0;
- while (c < zi.uncompressed_size)
- {
- int len = zi.uncompressed_size - c;
- if (len > 8192) len = 8192;
- unzReadCurrentFile(zip, buf, 8192);
- fwrite(buf, len, 1, fp);
- c += 8192;
- }
- fclose(fp);
- free(buf);
- }
- unzClose(zip);
- return 0;
- }
- int Byte_zip(lua_State *pL)
- {
- zip_fileinfo zi = { 0 };
- const char *filenamezip = lua_tostring(pL, 1);
- int n = lua_gettop(pL);
- int i;
- zipFile zip = zipOpen(filenamezip, APPEND_STATUS_CREATE);
- for (i = 2; i <= n; i++)
- {
- const char *filename = lua_tostring(pL, i);
- FILE *fp;
- if ((fp = fopen(filename, "rb")) == NULL)
- {
- break;
- }
- fseek(fp, 0, SEEK_END);
- int length = ftell(fp);
- fseek(fp, 0, 0);
- char* s = malloc(length + 1);
- fread(s, length, 1, fp);
- fclose(fp);
- get_file_date(filenamezip, &zi.dos_date);
- //zi.dos_date = time(NULL);
- zipOpenNewFileInZip(zip, filename, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
- zipWriteInFileInZip(zip, s, length);
- zipCloseFileInZip(zip);
- free(s);
- }
- zipClose(zip, NULL);
- return 0;
- }
- int Byte_loadfilefromzip(lua_State *pL)
- {
- char *p = (char *)lua_touserdata(pL, 1);
- const char *filenamezip = lua_tostring(pL, 2);
- const char *filename = lua_tostring(pL, 3);
- int start = (int)lua_tonumber(pL, 4);
- int length = (int)lua_tonumber(pL, 5);
- unzFile zip;
- unz_file_info zi = { 0 };
- zip = unzOpen(filenamezip);
- if (unzLocateFile(zip, filename, NULL) != UNZ_OK)
- {
- return 0;
- }
- char s[100];
- unzGetCurrentFileInfo(zip, &zi, s, 100, NULL, 0, NULL, 0);
- unzOpenCurrentFile(zip);
- const int size_buf = 8192;
- void* buf = malloc(size_buf);
- void* buf2 = malloc(zi.uncompressed_size);
- int c = 0;
- while (c < zi.uncompressed_size)
- {
- int len = zi.uncompressed_size - c;
- if (len > size_buf) len = size_buf;
- unzReadCurrentFile(zip, buf, size_buf);
- memcpy((char*)buf2+c,buf,len);
- c += size_buf;
- }
- unzClose(zip);
- memcpy(p, (char*)buf2+start,length);
- free(buf);
- free(buf2);
- return 0;
- }
复制代码
jymain.c里面初始化lua函数名的地方当然也要改一下:
- static const struct luaL_Reg bytelib [] = {
- {"create", Byte_create},
- {"loadfile", Byte_loadfile},
- {"savefile", Byte_savefile},
- {"unzip", Byte_unzip},
- {"zip", Byte_zip},
- {"get16", Byte_get16},
- {"set16", Byte_set16},
- {"getu16", Byte_getu16},
- {"setu16", Byte_setu16},
- {"get32", Byte_get32},
- {"set32", Byte_set32},
- {"getstr", Byte_getstr},
- {"setstr", Byte_setstr},
- {NULL, NULL}
- };
复制代码
这样就添加了两个专用于压缩或者解压的函数Byte.zip和Byte.unzip。它们的参数个数都是2个到无限多个。用法如下:
- Byte.unzip('data/save/1.zip', 'r.grp','d.grp','s.grp')
- Byte.zip('data/save/1.zip', 'r.grp','d.grp','s.grp')
复制代码
某些情况下如果只需要解压r.grp,也可以写:
- Byte.unzip('data/save/1.zip', 'r.grp')
复制代码
在任务完成后可以用os.remove删除文件。
但是需要注意,压缩的时候是新建一个压缩包,故一定要一次将所有文件都写完。
|