基于策略模式和简单工厂模式实现zip、tar、rar、7z四种压缩文件格式的解压

推荐语
这篇技术文章深入探讨了基于策略模式和简单工厂模式实现四种常见压缩文件格式的解压方法。通过阅读该文章,你将了解到如何利用这两种设计模式来实现灵活、可扩展的解压功能,同时适应不同的压缩文件格式。如果你对设计模式和文件处理感兴趣或刚好碰到类似的情况,那么这篇文章绝对值得一读。它会为你打开一个新的思路,并帮助你提升在软件开发中的技能和效率。
需求描述与分析
最近我遇到了一个需求,需要上传一个压缩包文件,其中包含目录和文件。上传成功后,后台会自动解压该文件,并保持压缩包内目录和文件的结构不变,然后将该结构渲染到页面上。
这个需求其实相对来说非常简单,实现起来并不困难。为了满足需求,我们需要解决以下三个问题:
- 压缩包文件有多种格式,例如ZIP、RAR、TAR等等,我们需要支持哪些格式?
- 如何选择合适的技术或工具来自动化地解压这些不同格式的文件?
- 在解压压缩包的同时,如何解析出里面的目录、文件之间的关系和结构,以便被正确地渲染到前端页面上?
实现原理
先解决第一个问题:压缩包文件的格式有很多,要支持多少种?
下面这四种相对比较常见,支持解析的格式暂时定为这四种:
- ZIP (.zip):ZIP 是最常见的压缩文件格式之一,多数操作系统都默认支持它。ZIP 文件通常用于在网络或电子邮件中传输文件,以及在本地计算机上备份和存档文件。
- TAR (.tar):TAR 是一种用于将多个文件和文件夹打包成一个单独的文件的文件格式。与其他压缩格式不同,TAR 不会对文件进行压缩,仅用于打包和归档文件。
- RAR (.rar):RAR 是另一种常见的压缩文件格式,它可以压缩许多文件,并提供比 ZIP 更好的压缩率。RAR 格式通常用于将大型文件分成多个部分,以便在互联网上分发和下载。
- 7Z (.7z):7Z 是一种开源的压缩文件格式,可提供比其他压缩文件格式更高的压缩率。7Z 文件通常用于压缩大型文件和文件夹,以便在网络上传输和存储。
第二个问题:如何解压这些不同格式的文件?
支付的压缩文件的格式暂定为上面四种格式的压缩包文件那如何对这些不同格式的压缩包文件进行解压操作呢?如文章标题,基于策略模式和 简单工厂模式先实现上面四种格式的压缩文件解压,具体怎么实现呢?
- 定义一个解压策略的抽象接口,内部定义一个抽象方法,作用是执行解压操作,但是这里不提供具体实现,具体实现由不同格式的具体解压策略来实现,这个方法的输入参数采用java标准的输入流,方便与其他业务对象,输出参数则是一个List集合类型,集合内存储的是解压文件的FileObj对象;
- 分别根据四种压缩文件格式,定义四个不同的解压策略实现类,这四个解压策略实现类来实现上面的解压策略抽象接口,重写接口的抽象方法,方法的业务逻辑是来执行具体格式的压缩文件的解压操作;
- 再定义一个解压策略的简单工厂类,用于根据不同的后缀,生成不同的解压策略,这个工工厂类最大的意义莫过于实现了解压客户端业务与具体解压操作的解耦;如果后续业务变更,需要新增其他格式的压缩文件解压,可以实现一个具体的解压策略类,然后再扩展一下这里的工厂类;解压客户端业务不需要做任何变更,这也符合设计模式中的单一职责;
第三个问题:压缩包文件解压的同时,怎么解析出压缩包里面的目录、文件的关系和结构?
- 从压缩包文件中解析出文件后,解压结果是一个包含FileObj对象的集合,FileObj对象包含了三个属性:1、文件在压缩包内的全路径(包含有文件名称、后缀);2、文件后缀;3、文件的全部字节(这里封装为字节的目的是方便,后面的处理,如写入本地、写入远程文件服务器等);
- 从解析结果中提取出文件在压缩包内的全路径;然后再进一步处理,转换为一个包含FileDir类型对象的集合,FileDir对象中有两个重要属性当前文件或目录的唯一标识和其父级的唯一标识,据此可以构建出一个树形结构,也就还原了压缩包里面的目录、文件的关第和结构;
实现方案
mavne依赖
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.24.0</version></dependency><dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding</artifactId><version>16.02-2.01</version></dependency><dependency><groupId>org.tukaani</groupId><artifactId>xz</artifactId><version>1.9</version></dependency><dependency><groupId>com.github.junrar</groupId><artifactId>junrar</artifactId><version>7.5.5</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding-all-platforms</artifactId><version>16.02-2.01</version></dependency><dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.12</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.23</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.32</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.6</version></dependency>
FileObj和FileDir
FileObj:从压缩包中解压出的每一个文件,封装到一个FileObj对象中,FileObj对象有三个属性:1、文件在压缩包内的全路径(包含有文件名称、后缀);2、文件后缀;3、文件的全部字节(这里封装为字节的目的是方便,后面的处理,如写入本地、写入远程文件服务器等)
@Data
public class FileObj {/*** 压缩包内文件全路径*/private String filePath;/*** 压缩包内文件后缀*/private String suffix;/*** 压缩包内文件的字节*/private byte[] bytes;
}
FileDir:把压缩包文件里的每一个目录封装成一个FileDir对象,FileDir对象包有六个属性:1、目录名称;2、目录级别,根目录为1,其子目录依次递增;3、父级目录的名称,如果是根目录,则父级目录为空;4、目录的唯一标识;5、父级目录的唯一标识;6、当前节点的孩子节点;这里注意一下要重写一个hashCode和equals方法,因为在解析压缩文件内的目录、文件的关系和结构时,使用了Set集合的去重功能;
@Data
public class FileDir{/*** 类型,1:目录;2:文件;*/private Integer docType=1;/*** 目录名称*/private String docName;/*** 目录级别,根目录为1,其子目录依次递增*/private Integer level;/*** 父级目录名称*/private String parentDocName;/*** 目录唯一标识*/private Long id;/*** 父级目录唯一标识*/private Long parentId;/*** 当前节点的孩子节点*/private List<FileDir> children;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;FileDir fileDir = (FileDir) o;if (!Objects.equals(docType, fileDir.docType)) return false;if (!Objects.equals(docName, fileDir.docName)) return false;if (!Objects.equals(level, fileDir.level)) return false;if (!Objects.equals(parentDocName, fileDir.parentDocName))return false;if (!Objects.equals(id, fileDir.id)) return false;if (!Objects.equals(parentId, fileDir.parentId)) return false;return Objects.equals(children, fileDir.children);}@Overridepublic int hashCode() {int result = docType != null ? docType.hashCode() : 0;result = 31 * result + (docName != null ? docName.hashCode() : 0);result = 31 * result + (level != null ? level.hashCode() : 0);result = 31 * result + (parentDocName != null ? parentDocName.hashCode() : 0);result = 31 * result + (id != null ? id.hashCode() : 0);result = 31 * result + (parentId != null ? parentId.hashCode() : 0);result = 31 * result + (children != null ? children.hashCode() : 0);return result;}
}
UnZipStrategy

UnZipStrategy:是解压策略的抽象接口,内部定义一个抽象方法,作用是执行解压操作,具体实现由不同格式的具体解压策略来实现,这个方法的输入参数采用java标准的输入流,方便与其他业务对象,输出参数则是一个List集合类型,集合内存储的是解压文件的FileObj对象;
public interface UnZipStrategy {List<FileObj> analysis(InputStream inputStream);
}
ZipAnalysisStrategy
ZipAnalysisStrategy:是zip格式的压缩文件的解压策略,实现UnZipStrategy抽象接口,具体来执行zip格式的压缩文件的解压操作;
@Slf4j
public class ZipAnalysisStrategy implements UnZipStrategy {@Overridepublic List<FileObj> analysis(InputStream inputStream) {List<FileObj> list = new ArrayList<>();ArchiveInputStream ais = new ZipArchiveInputStream(inputStream);ArchiveEntry entry;try {while ((entry = ais.getNextEntry()) != null) {if (!entry.isDirectory()) {FileObj fileObj = extractFile(ais, entry);list.add(fileObj);}}ais.close();inputStream.close();} catch (IOException e) {log.error("zip格式压缩文件在解压时发生错误:",e);throw new RuntimeException(e);}return list;}private FileObj extractFile(ArchiveInputStream ais, ArchiveEntry entry) throws IOException {String name = entry.getName();log.info("解析文件:{}",name);int index = name.lastIndexOf(".");String suffix = name.substring(index + 1);FileObj fileObj = new FileObj();fileObj.setFilePath(entry.getName());fileObj.setSuffix(suffix);ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int length;while ((length = ais.read(buffer)) > 0) {byteArrayOutputStream.write(buffer, 0, length);}byte[] bytes = byteArrayOutputStream.toByteArray();fileObj.setBytes(bytes);byteArrayOutputStream.close();return fileObj;}
}
TarAnalysisStrategy
TarAnalysisStrategy:是tar格式的压缩文件的解压策略,实现UnZipStrategy抽象接口,具体来执行tar格式的压缩文件的解压操作;
@Slf4j
public class TarAnalysisStrategy implements UnZipStrategy {@Overridepublic List<FileObj> analysis(InputStream inputStream) {List<FileObj> list=new ArrayList<>();FileObj fileObj;TarInputStream tarInputStream = new TarInputStream(inputStream, 1024 * 2);TarEntry entry;try {while ((entry = tarInputStream.getNextEntry()) != null) {if (!entry.isDirectory()) {fileObj=new FileObj();String name = entry.getName();int index = name.lastIndexOf(".");String suffix = name.substring(index + 1);fileObj.setFilePath(name);fileObj.setSuffix(suffix);int count;byte data[] = new byte[2048];ByteArrayOutputStream outputStream = new ByteArrayOutputStream();while ((count = tarInputStream.read(data)) != -1) {outputStream.write(data, 0, count);}byte[] byteArray = outputStream.toByteArray();outputStream.close();fileObj.setBytes(byteArray);list.add(fileObj);}}inputStream.close();tarInputStream.close();} catch (IOException e) {log.error("tar格式压缩文件在解压时发生错误:",e);throw new RuntimeException(e);}return list;}
}
SevenZAnalysisStrategy
SevenZAnalysisStrategy:是7z格式的压缩文件的解压策略,实现UnZipStrategy抽象接口,具体来执行7z格式的压缩文件的解压操作;
@Slf4j
public class SevenZAnalysisStrategy implements UnZipStrategy {@Overridepublic List<FileObj> analysis(InputStream inputStream) {List<FileObj> list = new ArrayList<>();FastByteArrayOutputStream read = IoUtil.read(inputStream);byte[] byteArray = read.toByteArray();SeekableInMemoryByteChannel seekableInMemoryByteChannel = new SeekableInMemoryByteChannel(byteArray);try {SevenZFile sevenZFile = new SevenZFile(seekableInMemoryByteChannel);// 创建输出目录SevenZArchiveEntry entry;while ((entry = sevenZFile.getNextEntry()) != null) {if (!entry.isDirectory()) {FileObj fileObj = new FileObj();String name = entry.getName();log.info("解析文件:{}",name);int index = name.lastIndexOf(".");String suffix = name.substring(index + 1);fileObj.setFilePath(name);fileObj.setSuffix(suffix);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();int len = 0;byte[] b = new byte[2048];while ((len = sevenZFile.read(b)) != -1) {outputStream.write(b, 0, len);}byte[] bytes = outputStream.toByteArray();outputStream.close();fileObj.setBytes(bytes);list.add(fileObj);}}inputStream.close();read.close();seekableInMemoryByteChannel.close();} catch (IOException e) {log.error("7z格式的压缩文件在解压时发生错误:",e);throw new RuntimeException(e);}return list;}
}
RarAnalysisStrategy
RarAnalysisStrategy:是rar格式的压缩文件的解压策略,实现UnZipStrategy抽象接口,具体来执行rar格式的压缩文件的解压操作;这个格式的压缩文件解压起来稍微有点费力,用到了一个回调RarExtractCallback类,这个RarExtractCallback类实现IArchiveExtractCallback接口,重写getStream()和setOperationResult(),来实现压缩文件的解压;
@Slf4j
public class RarAnalysisStrategy implements UnZipStrategy {@Overridepublic List<FileObj> analysis(InputStream inputStream) {try {byte[] bytes = IoUtil.readBytes(inputStream);ByteArrayStream byteArrayStream = new ByteArrayStream(bytes, false);IInArchive inArchive = SevenZip.openInArchive(null, byteArrayStream);int[] in = new int[inArchive.getNumberOfItems()];for (int i = 0; i < in.length; i++) {in[i] = i;}//使用回调函数RarExtractCallback rarExtractCallback = new RarExtractCallback(inArchive);inArchive.extract(in, false, rarExtractCallback);byteArrayStream.close();inputStream.close();return rarExtractCallback.getFileObjs();} catch (IOException e) {log.error("rar格式的压缩文件在解压时发生错误:", e);throw new RuntimeException(e);}}
}
@Slf4j
public class RarExtractCallback implements IArchiveExtractCallback {private Integer index;private IInArchive inArchive;private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();@Getterprivate List<FileObj> fileObjs=new ArrayList<>();public RarExtractCallback(IInArchive inArchive) {this.inArchive = inArchive;}@Overridepublic void setCompleted(long arg0) throws SevenZipException {}@Overridepublic void setTotal(long arg0) throws SevenZipException {}@Overridepublic ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {this.index=index;boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);return data -> {if (!isFolder) {try {outputStream.write(data);} catch (IOException e) {log.error("rar格式的压缩文件在解压时发生错误:",e);throw new RuntimeException(e);}}return data.length;};}@Overridepublic void prepareOperation(ExtractAskMode arg0) throws SevenZipException {}@Overridepublic void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {String path = (String) inArchive.getProperty(index, PropID.PATH);boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);if (!isFolder) {FileObj fileObj=new FileObj();fileObj.setFilePath(path);log.info("解析文件:{}",path);int index1 = path.lastIndexOf(".");String suffix = path.substring(index1 + 1);fileObj.setSuffix(suffix);byte[] byteArray = outputStream.toByteArray();outputStream.reset();fileObj.setBytes(byteArray);fileObjs.add(fileObj);}}
}
UnZipStrategyFactory
UnZipStrategyFactory:解压策略的简单工厂类,用于根据不同的后缀,生成不同的解压策略,最大的意义莫过于实现了解压主业务与具体解压操作的解耦;
public class UnZipStrategyFactory {public static UnZipStrategy generate(String suffix){UnZipStrategy strategy;switch (suffix){case "zip":strategy=new ZipAnalysisStrategy();break;case "tar":strategy=new TarAnalysisStrategy();break;case "rar":strategy=new RarAnalysisStrategy();break;case "7z":strategy=new SevenZAnalysisStrategy();break;default:strategy=null;break;}return strategy;}
}
FileDirProcessor
FileDirProcessor:用于从压缩包里解压出的文件列表里,解析出目录与文件的结构,即包含FileDir对象的集合;
public class FileDirProcessor {public static List<FileDir> process(List<String> list) {//解析和去重Set<FileDir> sets = new HashSet<>();if (CollUtil.isNotEmpty(list)) {for (String dirStr : list) {String[] split = dirStr.split("/");if (split.length > 0) {if (split.length == 1) {FileDir fileDir = new FileDir();fileDir.setDocName(split[0]);fileDir.setDocType(2);fileDir.setLevel(1);fileDir.setParentDocName("");sets.add(fileDir);} else {for (int i = 0; i < split.length; i++) {FileDir fileDir = new FileDir();fileDir.setDocName(split[i]);fileDir.setLevel(i + 1);fileDir.setDocType(1);if (i == 0) {fileDir.setParentDocName("");}if (i == (split.length - 1)) {fileDir.setDocType(2);fileDir.setParentDocName(split[i - 1]);}if (i != 0 && i != split.length - 1) {fileDir.setParentDocName(split[i - 1]);}sets.add(fileDir);}}}}}if (CollUtil.isNotEmpty(sets)) {//设置idMap<String, Long> map = new HashMap<>();Snowflake snowflake = IdUtil.getSnowflake();for (FileDir fileDir : sets) {long id = snowflake.nextId();fileDir.setId(id);map.put(fileDir.getLevel() + fileDir.getDocName(), id);}//设置父idfor (FileDir fileDir : sets) {if (fileDir.getLevel() == 1) {fileDir.setParentId(0L);} else {Long parentId = map.get((fileDir.getLevel() - 1) + fileDir.getParentDocName());fileDir.setParentId(parentId);}}}return new ArrayList<>(sets);}
}
FileDirTree
FileDirTree:在FileDirProcessor类的解析结果中定义了两个关键东西,当前文件或目录的唯一标识id和父id,FileDirTree的作用用在于把FileDirProcessor类的解析结果转换成一种树形结构,以便在页面上渲染展示;
public class FileDirTree {public List<FileDir> nodeList;public FileDirTree(List<FileDir> nodeList) {this.nodeList = nodeList;}private List<FileDir> getRootNode() {List<FileDir> rootNodeList = new ArrayList<>();for (FileDir treeNode : nodeList) {if (0 == treeNode.getParentId()) {rootNodeList.add(treeNode);}}return rootNodeList;}public List<FileDir> buildTree() {List<FileDir> treeNodes = new ArrayList<FileDir>();for (FileDir treeRootNode : getRootNode()) {treeRootNode = buildChildTree(treeRootNode);treeNodes.add(treeRootNode);}return treeNodes;}private FileDir buildChildTree(FileDir pNode) {List<FileDir> childTree = new ArrayList<FileDir>();for (FileDir treeNode : nodeList) {if (treeNode.getParentId().equals(pNode.getId())) {childTree.add(buildChildTree(treeNode));}}pNode.setChildren(childTree);return pNode;}}
单元测试
@Testpublic void test4() throws IOException {String fileName = "e:/zip/test.zip";int index = fileName.lastIndexOf(".");String suffix = fileName.substring(index + 1);//构建解压策略UnZipStrategy unZipStrategy = UnZipStrategyFactory.generate(suffix);//开始解压List<FileObj> analysis = unZipStrategy.analysis(Files.newInputStream(Paths.get(fileName)));//从解压结果中获取解压文件的全路径List<String> list = analysis.stream().map(FileObj::getFilePath).collect(Collectors.toList());
// log.info(JSONUtil.toJsonStr(list));
// this.saveFile(analysis, suffix);//根据解压文件的全路径解析出压缩包内文件和目录的树形结构List<FileDir> process = FileDirProcessor.process(list);FileDirTree fileDirTree = new FileDirTree(process);List<FileDir> tree = fileDirTree.buildTree();log.info(JSONUtil.toJsonStr(tree));}

源码下载
如果想获取完整的示例代码,可以从下面这个地址clone:
凡夫贩夫 / unzip-demo · GitCode
写在最后
感谢您阅读我的文章,如果您觉得我的内容对您有所启发或帮助,欢迎关注我并给我点赞。
相关文章:
基于策略模式和简单工厂模式实现zip、tar、rar、7z四种压缩文件格式的解压
推荐语 这篇技术文章深入探讨了基于策略模式和简单工厂模式实现四种常见压缩文件格式的解压方法。通过阅读该文章,你将了解到如何利用这两种设计模式来实现灵活、可扩展的解压功能,同时适应不同的压缩文件格式。如果你对设计模式和文件处理感兴趣或刚好…...
修改jenkins的目录(JENKINS_HOME)
默认JENKINS_HOME是/var/lib/jenkins/ 现要修改为/home/jenkins_data/jenkins 最开始 sudo cp -a /var/lib/jenkins/ /home/jenkins_data/ 然后如下操作: 1、首先 /etc/sysconfig/jenkins:jenkins配置文件,“端口”,“JENKIN…...
Bytebase:统一数据库 CI/CD 解决方案 | 开源日报 No.128
bytebase/bytebase Stars: 7.9k License: NOASSERTION Bytebase 是一个数据库 CI/CD 解决方案,为开发人员和 DBA 提供统一的工具来管理不同数据库系统的开发生命周期。其主要功能包括标准化操作流程、SQL 代码审查、GitOps 集成以及数据访问控制等。关键特性和核心…...
History对象常用方法
文章目录 一、什么是History对象二、使用History对象 一、什么是History对象 history 对象来保存浏览器历史记录信息,也就是用户访问的页面。浏览器的前进与后退功能本质上就是 history 的操作。history 对象记录了用户浏览过的页面,通过该对象提供的 A…...
修改源码,element的el-table合并,处理合并产生的hover样式问题
1、确认自己element-ui的版本号 2、此element-ui下的lib包是修改过hover样式的包,如何替换自己文件下的node_modules中的包 修改后将lib文件夹中文件替换你项目中/node_module/element-ui/Lib中的文件问题??如果替换开发环境中的node_module的包无法升级到测试环境,因为nod…...
IoT 物联网常用协议
物联网协议是指在物联网环境中用于设备间通信和数据传输的协议。根据不同的作用,物联网协议可分为传输协议、通信协议和行业协议。 传输协议:一般负责子网内设备间的组网及通信。例如 Wi-Fi、Ethernet、NFC、 Zigbee、Bluetooth、GPRS、3G/4G/5G等。这些…...
使用java备份和恢复SQLServer表数据
需求 近来工作中遇到一个问题,内网办公系统中的数据需要导出到外网中进行查询,外网的数据库中还有一些表存储外网的数据,因此无法使用全库备份恢复功能来满足需求。即只从内网数据库中导出若干表的内容至外网数据库的对应表。 其他解决方案…...
27 UVM queue
uvm_queue类构建一个动态队列,该队列将按需分配并通过引用传递。 uvm_queue类声明: class uvm_queue #( type T int ) extends uvm_object 1 uvm_queue class hierarchy 2 uvm_queue class Methods 3 UVM Queue Example 在下面的示例中,…...
聊聊自动化测试的分层实践
技术群里,有同学聊起了各自在实践自动化测试时遇到的各种问题,最典型的就是落地难度和投入产出比。毕竟在当前这个时间节点,单纯的技术实践如果不能带来实际可见的业务价值,确实很影响个人绩效和团队产出。 这篇文章,…...
LVS那点事
LVS 原理 IPVS LVS 的 IP 负载均衡技术是通过 IPVS 模块来实现的,IPVS 是 LVS 集群系统的核心软件,它的主要作用是:安装在 Director Server 上,同时在 Director Server 上虚拟出一个 IP 地址,用户必须通过这个虚拟的…...
2022-2023年度广东省职业院校学生专业技能大赛“软件测试”赛项接口测试训练题目
接口测试 新增接口脚本编写和执行测试,并执行脚本。 (1)商品单位添加接口描述如下: 接口功能:提供商品单位新增处理。 接口地址(根据实际系统IP及端口自行替换): http://XX.XX.XX.XX:XXXX/prod-api/manager/category/add。 请求方式:POST。 请求参数:...
[Python][LeetCode]28. 找出字符串中第一个匹配项的下标
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 示例 1: 输入:haystack &quo…...
Prometheus监控mysql
docker-compose.yml 创建mysql mkdir/data/mysql -pcat > /data/mysql/docker-compose.yml << EOF version: 3.1 services:db:image: mysql:8.0restart: alwayscontainer_name: mysqlenvironment:TZ: Asia/ShanghaiLANG: en_US.UTF-8MYSQL_ROOT_PASSWORD: 123456comm…...
骑砍战团MOD开发(30)-游戏大地图map.txt
骑砍1战团mod开发-大地图制作方法_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1rz4y1c7wH/ 一.骑砍游戏大地图 骑砍RTS视角游戏大地图 大地图静态模型(map.txt) 军团/城镇图标(module_parties.py). 骑砍大地图的战争迷雾和天气通过API进行管理和控制: # Weather-h…...
关于 bringup sensor 时,曝光时间异常的问题排查
1、问题背景 这两天在配置 sc223a 这颗 sensor 的驱动,按 datasheet 的要求配置 sensor 的曝光后,发现最大曝光时间增加了一倍, sensor setting 用的是30fps ,理论上最大的绝对曝光时间应该是 33ms 才正确,但实际用 …...
linux用户态与内核态通过字符设备交互
linux用户态与内核态通过字符设备交互 简述 Linux设备分为三类,字符设备、块设备、网络接口设备。字符设备只能一个字节一个字节读取,常见外设基本都是字符设备。块设备一般用于存储设备,一块一块的读取。网络设备,Linux将对网络…...
如何高效查询文件:Linux 下的多种方法详解
如何高效查询文件:Linux 下的多种方法详解 在日常工作中,我们经常需要查找文件,无论是寻找特定的代码文件、配置文件还是其他文档。Linux 提供了多种强大的命令和工具,通过巧妙地使用管道符,我们可以将这些命令组合起来…...
记矩阵基础概念
转自up:Naruto_Qcsdn:三维空间几何变换矩阵 先贴个站里分享的基础概念。 learn form 肥猫同学VFX b站:会用transform就会用矩阵 移动 旋转 缩放 1.transofrm ——输出变化矩阵 可以移动transform查看变化去理解 位移 缩放 旋转 由此—…...
用html,js和layui写一个简单的点击打怪小游戏
介绍: 一个简单的打怪小游戏,点击开始游戏后,出现攻击按钮,击败怪物后可以选择继续下一关和结束游戏。 继续下一个怪兽的血量会增加5点,攻击按钮会随机变色。 效果图: html代码: <!DOCTYPE…...
[线代]不挂科猴博士
行列式的性质 行列式的计算及应用 矩阵的运算上(加减,相乘,取行列式) 矩阵的运算下(转置,逆,秩) 向量组与线性空间 解方程组...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
