//tar 文件打包 import zlib; import fsys; import fsys.file; import fsys.time; namespace fsys; class tar { ctor( tarPath,rootDir ){ var tarFile; if( rootDir ){ rootDir = ..io.exist(rootDir); if(!rootDir) return null,"错误的根目录路径"; } if( ! (tarPath?..fsys.createParentDir(tarPath) ) ) return null,"存储路径错误"; if( ..string.match(tarPath,"<.gz>|<.tgz>$") ){ tarFile = ..zlib.gzFile(tarPath,"wb") } else { tarFile = ..io.file(tarPath,"w+b",0x10) } if(!tarFile) return null,"创建tar文件失败"; var tarHeader = tar_header(); var buffer = ..raw.buffer(512); var zeroBuffer = ..raw.buffer(512,0); this.utf8 = true; ..table.gc(this,"close"); }; addFile = function(path) { path = ..io.exist(path); if(!rootDir) rootDir = ..fsys.getParentDir(path); var name = path ? ..fsys.path.relative(path,rootDir,false); if(!name) error("文件路径错误",2); name = ..string.replace( name,"@\", "/" ); tarHeader.name = this.utf8 ? name : ..string.fromto(name,65001,0); var file = ..fsys.file(path,"rb"); if(!file) error("读取文件失败:" + path,2) tarHeader.linkflag = '0'#; var size = file.size(1); tarHeader.size = ..string.format('%011o\0',( file.size(1) ) ); tarHeader.mtime = ..string.format('%011o\0',tonumber( file.getFileTime().write.toSystemTime() ) ); tarHeader.mode = '0100777\0';//..string.format('%07o\0',8#0100777); tarHeader.chksum = checksum(tarHeader); tarFile.write(tarHeader); if( this.onWriteFile) this.onWriteFile(name); var readSize = file.readBuffer(buffer,512); while( readSize ){ if( this.onWriteFileBock ) this.onWriteFileBock(name,readSize,size); tarFile.writeBuffer( buffer,readSize ); if( readSize < 512 ){ tarFile.writeBuffer( zeroBuffer,512 - readSize ); break; } readSize = file.readBuffer(buffer,512); } file.close(); } addFolder = function(path){ path = ..io.exist(path); if(!rootDir) rootDir = ..fsys.getParentDir(path); var name = path ? ..fsys.path.relative(path,rootDir,false); if(!name) error("文件路径错误",2); name = ..string.replace( name,"@@\", "/" ); if( name[#name] != '/'# ) name = name + "/"; tarHeader.name = this.utf8 ? name : ..string.fromto(name,65001,0); tarHeader.linkflag = '5'#; tarHeader.size = ..string.format('%011o\0',0); tarHeader.mode = '0040777\0';//..string.format('%07o\0',8#040777); var file = ..fsys.file(path,,,,0x2000000/*_FILE_FLAG_BACKUP_SEMANTICS*/); tarHeader.mtime = ..string.format('%011o\0',tonumber( file.getFileTime().write.toSystemTime().local() ) ); file.close(); tarHeader.chksum = checksum(tarHeader); tarFile.write(tarHeader); if( this.onWriteDir) this.onWriteDir(name); } pack = function(path,pattern,selfName=true){ if( !rootDir ){ if(selfName){ rootDir = ..fsys.getParentDir(path); this.addFolder(path); } else { rootDir = path; } } ..fsys.enum( path,pattern,function(dir,filename,fullpath,findData){ ..io.print(fullpath) if(filename) this.addFile(fullpath); else this.addFolder(fullpath); } ); }; close = function(){ if( tarFile ){ if( tarFile.seek() ){ tarFile.writeBuffer( zeroBuffer,512 ); tarFile.writeBuffer( zeroBuffer,512 ); } tarFile.close(); tarFile = null; } } } namespace tar { class tar_header{ byte name[100]; byte mode[8]; byte uid[8] = '0000000\0'; byte gid[8] = '0000000\0'; byte size[12]; byte mtime[12]; byte chksum[8]; byte linkflag; byte linkname[100]; byte magic[8] = 'ustar\x0000';//后 2 位为 version byte uname[32]; byte gname[32]; byte devmajor[8]; byte devminor[8]; byte prefix[155]; byte data[12] //对齐作用 } var __nchkshum_fileds = { byte chksum[8]={};byte linkflag = 1 } checksum = function(tarHeader){ var chksum = 0x100 + tarHeader.linkflag ; for(k,v in tarHeader){ if( v ? ( ! __nchkshum_fileds[k] ) ){ for(i=1;#v ){ chksum = chksum + v[i]; } } } return ..string.format('%06o\0 ', chksum ) } } /**intellisense() fsys.tar = tar文件打包 fsys.tar(.("tar文件路径","打包根目录") = 参数一可以是tar文件或tar.gz文件路径,\n如果省略根目录参数,打包首个文件则取其父目录为根目录 fsys.tar() = !fsys_tarfile. !fsys_tarfile.utf8 = 是否使用 UTF8 编码文件名。\n默认启用 UTF8 编码,建议保持默认值。 !fsys_tarfile.pack(.(目录路径,文件通配符,是否添加该目录名字) = 打包目录下的所有文件 !fsys_tarfile.addFile(.("文件路径") = 添加文件,\n必须是指定根目录下的文件 !fsys_tarfile.addFolder(.("文件路径") = 添加文件,\n必须是指定根目录下的子目录 !fsys_tarfile.close() = 关闭文件 !fsys_tarfile.onWriteFileBock = @.onWriteFileBock = function( filename,writeSize,fileSize){ io.print( filename,writeSize,fsys.formatSize(fileSize) );__/*写入文件块回调函数*/ } !fsys_tarfile.onWriteDir = @.onWriteDir = function( filename ){ __/*添加目录回调函数*/ } !fsys_tarfile.onWriteFile = @.onWriteFile = function( filename ){ __/*添加目录回调函数*/ } end intellisense**/