//zip 压缩 import zlib; import fsys; import fsys.file; var dll = zlib._dll; namespace zlib; class zip{ ctor( path,localDir,append ){ if( localDir ? ( ! ..fsys.isDir(localDir) ) ){ error("参数@2指定的路径必须是一个目录",2); } var zipFile = zipOpen64(..io.fullpath(path) ,append?2:0); if(!zipFile)error("压缩文件路径参数错误",2); path = ..io.exist(path); if(!path) error("压缩源目录路径错误",2) var bufferPrev; ..table.gc(this,"close"); }; beginWrite = function(fileName,password,level=9){ var crcForCrypting,zip64; var info = zip_fileinfo(); var toPath = fileName[["to"]] if(toPath){ fileName = fileName[["from"]]; if(!fileName) error("缺少源路径"); } fileName = ..fsys.longpath(fileName); var attr = ..fsys.attrib(fileName); if( attr == -1) error("路径参数错误",2); var isDir = ..fsys.isDir(fileName); if( isDir ){ fileName = ..fsys.path.addBackslash(fileName); } var file,err = ..fsys.file(fileName,"rbR") if(!file)return null,err; if( !isDir ){ zip64 = file.size64().greaterThan(0xffffffff); if( password ){ var crc32 = ..string.crc32; var bufsize = 0x100000; var buffer = ..raw.buffer(bufsize); var readSize = file.readBuffer(buffer); while ( readSize ){ crcForCrypting = crc32(buffer,crcForCrypting,readSize) readSize = file.readBuffer(buffer); }; } } if( crcForCrypting === null ) crcForCrypting = 0; var ftm = file.getFileTime().write; file.close(); ftm.local(); info.dosDate = ftm.toDosTime(); info.external_fa = attr; toPath = toPath || ..fsys.path.relative(fileName,localDir,false); if(!#toPath)return; toPath = ..string.replace(toPath,"\\","/"); if (zipOpenNewFileInZip4_64(zipFile,toPath,info, , 0, , 0, , 8/*_Z_DEFLATED*/, level, 0,-15/*_Z_MAX_WBITS*/, 8/*_Z_DEF_MEM_LEVEL*/, 0/*_Z_DEFAULT_STRATEGY*/,password, crcForCrypting, 0/*_VERSIONMADEBYDOS*/, 0x800, zip64) != 0/*_ZIP_OK*/){ return; } return true; }; writeBuffer = function(buffer,l){ var m = #buffer; if( !l ) l = m; elseif( l > m ) l = m; elseif( l < 0 ) return 0; return zipWriteInFileInZip(zipFile,buffer,l); }; endWrite = function(){ zipCloseFileInZip(zipFile); }; writeDir = function(pathInfo,password){ if( this.beginWrite(pathInfo,password) ){ this.endWrite(); return true; } }; eachWriteFile = function(pathInfo,password,bufSize = 0xA00000,level){ path = pathInfo[["from"]] || pathInfo; if(!..io.exist(path) )error("路径参数错误",2); if( ( bufSize <= 0 ) || (! this.beginWrite(pathInfo,password,level) ) )return function(){}; var buffer; if( #bufferPrev = bufSize ){ buffer = bufferPrev; } else{ buffer = ..raw.buffer(bufSize); }; var file = ..io.file(path,"rb") return function(){ var len = file.readBuffer(buffer) if( len ){ this.writeBuffer(buffer,len); return len; } },function(){ this.endWrite(); file.close(); }; } close = function(){ if(zipFile){ zipClose( zipFile ); zipFile = null; } }; compress = function(compressPath,proc,password,level=9,bufSize = 0xA00000){ var toPath = compressPath[["to"]] if(toPath){ compressPath = ..io.exist(compressPath[["from"]]); if(!compressPath)error("压缩源文件路径错误",2); toPath = ..string.trimleft(toPath,"/\");//必须移除 if( !..fsys.isDir(compressPath) ){ for len in this.eachWriteFile({ from = compressPath; to = toPath; },password,bufSize,level){ if(proc)proc( len,compressPath ); } } else { ..fsys.enum(compressPath, "*.*", function(dir,file,fullpath,findData){ var subPath = ..fsys.path.relative(fullpath,compressPath,false); if(file){ for len in this.eachWriteFile({ from = fullpath; to = ..io.joinpath(toPath,subPath); },password,bufSize,level){ if(proc) proc( len,fullpath ); } } else{ this.writeDir({ from = fullpath; to = ..io.joinpath(toPath,subPath); },password); } } ); } return true; } var compressPath = ..io.exist(compressPath); if(!compressPath)error("压缩源文件路径错误",2); if( !..fsys.isDir(compressPath) ){ if(!localDir)localDir = ..fsys.getParentDir(compressPath); for len in this.eachWriteFile(compressPath,password,bufSize,level){ if(proc)proc( len,compressPath ); } } else { if(!localDir)localDir = compressPath; ..fsys.enum(compressPath, "*.*", function(dir,file,fullpath,findData){ if(file){ for len in this.eachWriteFile(fullpath,password,bufSize,level){ if(proc) proc( len,fullpath ); } } else{ this.writeDir(fullpath,password); } } ); } return true; } } namespace zip{ zipOpen64 = dll.api("zipOpen64W","pointer(ustring path,int append)"); zipClose = dll.api("zipClose","int(pointer file,string comment)"); zipOpenNewFileInZip4_64 = dll.api("zipOpenNewFileInZip4_64","int(POINTER file, str filename, struct zipfi,pointer extrafield_local, INT size_extrafield_local, pointer extrafield_global,INT size_extrafield_global,str comment , int method,int level,int raw,int windowBits,int memLevel,int strategy,string password,INT crcForCrypting,INT versionMadeBy,INT flagBase,bool zip64)"); zipCloseFileInZip = dll.api("zipCloseFileInZip","int(pointer file)"); zipWriteInFileInZip = dll.api("zipWriteInFileInZip","int(pointer file,POINTER buf,INT len)"); class zip_fileinfo { struct tmz_date = { INT second; INT minute; INT hour; INT day; INT month; INT year; }; INT dosDate; INT internal_fa; INT external_fa; } } //@guide [点这里查看使用范例](doc://example/File/Compression/zip.aardio) /**intellisense() zlib.zip(.(zip路径,根目录,是否追加) = 创建压缩文件对象。\n参数二,参数三都可以省略。\n如果不指定根目录,首先调用 compress 函数时将自动指定。\n如果首次压缩的是目录,则该目录设为根目录,否则文件的父目录设为根目录。\n如果压缩时路径参数传入包含 from,to 字段的表则忽略根目录配置。 zlib.zip() = !zlib_zip. !zlib_zip.beginWrite(.(文件路径,压缩密码,压缩级别) = 开始添加压缩文件,\n密码为可选参数,压缩级别可省略,默认为0 !zlib_zip.endWrite() = 添加压缩文件完成 !zlib_zip.writeBuffer(.(buffer,长度) = 参数@1 使用 raw.buffer 函数分配的 buffer 对象,\n长度可省略 !zlib_zip.close() = 关闭对象 !zlib_zip.writeDir(.(目录路径) = 添加目录 !zlib_zip.compress(文件路径,回调函数,压缩密码,压缩级别,缓冲区大小) = @.compress( "__/*参数 @1 可指定需要压缩的源目录或文件路径。\n也可指定一个表:由 from 字段指定源路径,to 字段指定目标路径。*/",\n function(len,path){\n ..io.print( len,path )\n }\n) _ZIP_OK=@0/*_ZIP_OK*/ _ZIP_EOF=@0/*_ZIP_EOF*/ _ZIP_ERRNO=@-1/*_ZIP_ERRNO*/ _ZIP_PARAMERROR=@-102/*_ZIP_PARAMERROR*/ _ZIP_BADZIPFILE=@-103/*_ZIP_BADZIPFILE*/ _ZIP_INTERNALERROR=@-104/*_ZIP_INTERNALERROR*/ end intellisense**/