当前位置: 首页 > news >正文

广州企业网站建设公司哪家好做商城网站的企业

广州企业网站建设公司哪家好,做商城网站的企业,网站建设相关书籍,深圳网站开发哪家服务专业推荐语 这篇技术文章深入探讨了基于策略模式和简单工厂模式实现四种常见压缩文件格式的解压方法。通过阅读该文章#xff0c;你将了解到如何利用这两种设计模式来实现灵活、可扩展的解压功能#xff0c;同时适应不同的压缩文件格式。如果你对设计模式和文件处理感兴趣或刚好… 推荐语 这篇技术文章深入探讨了基于策略模式和简单工厂模式实现四种常见压缩文件格式的解压方法。通过阅读该文章你将了解到如何利用这两种设计模式来实现灵活、可扩展的解压功能同时适应不同的压缩文件格式。如果你对设计模式和文件处理感兴趣或刚好碰到类似的情况那么这篇文章绝对值得一读。它会为你打开一个新的思路并帮助你提升在软件开发中的技能和效率。 需求描述与分析 最近我遇到了一个需求需要上传一个压缩包文件其中包含目录和文件。上传成功后后台会自动解压该文件并保持压缩包内目录和文件的结构不变然后将该结构渲染到页面上。 这个需求其实相对来说非常简单实现起来并不困难。为了满足需求我们需要解决以下三个问题 压缩包文件有多种格式例如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依赖 dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-compress/artifactIdversion1.24.0/version/dependencydependencygroupIdnet.sf.sevenzipjbinding/groupIdartifactIdsevenzipjbinding/artifactIdversion16.02-2.01/version/dependencydependencygroupIdorg.tukaani/groupIdartifactIdxz/artifactIdversion1.9/version/dependencydependencygroupIdcom.github.junrar/groupIdartifactIdjunrar/artifactIdversion7.5.5/version/dependencydependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependencydependencygroupIdnet.sf.sevenzipjbinding/groupIdartifactIdsevenzipjbinding-all-platforms/artifactIdversion16.02-2.01/version/dependencydependencygroupIdorg.apache.ant/groupIdartifactIdant/artifactIdversion1.10.12/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.30/version/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.23/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdversion1.7.32/version/dependencydependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.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 docType1;/*** 目录名称*/private String docName;/*** 目录级别根目录为1其子目录依次递增*/private Integer level;/*** 父级目录名称*/private String parentDocName;/*** 目录唯一标识*/private Long id;/*** 父级目录唯一标识*/private Long parentId;/*** 当前节点的孩子节点*/private ListFileDir 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 {ListFileObj analysis(InputStream inputStream); } ZipAnalysisStrategy ZipAnalysisStrategy是zip格式的压缩文件的解压策略实现UnZipStrategy抽象接口具体来执行zip格式的压缩文件的解压操作 Slf4j public class ZipAnalysisStrategy implements UnZipStrategy {Overridepublic ListFileObj analysis(InputStream inputStream) {ListFileObj 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 ListFileObj analysis(InputStream inputStream) {ListFileObj listnew ArrayList();FileObj fileObj;TarInputStream tarInputStream new TarInputStream(inputStream, 1024 * 2);TarEntry entry;try {while ((entry tarInputStream.getNextEntry()) ! null) {if (!entry.isDirectory()) {fileObjnew 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 ListFileObj analysis(InputStream inputStream) {ListFileObj 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 ListFileObj 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 ListFileObj fileObjsnew 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.indexindex;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 fileObjnew 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:strategynew ZipAnalysisStrategy();break;case tar:strategynew TarAnalysisStrategy();break;case rar:strategynew RarAnalysisStrategy();break;case 7z:strategynew SevenZAnalysisStrategy();break;default:strategynull;break;}return strategy;} } FileDirProcessor FileDirProcessor用于从压缩包里解压出的文件列表里解析出目录与文件的结构即包含FileDir对象的集合 public class FileDirProcessor {public static ListFileDir process(ListString list) {//解析和去重SetFileDir 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)) {//设置idMapString, 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 ListFileDir nodeList;public FileDirTree(ListFileDir nodeList) {this.nodeList nodeList;}private ListFileDir getRootNode() {ListFileDir rootNodeList new ArrayList();for (FileDir treeNode : nodeList) {if (0 treeNode.getParentId()) {rootNodeList.add(treeNode);}}return rootNodeList;}public ListFileDir buildTree() {ListFileDir treeNodes new ArrayListFileDir();for (FileDir treeRootNode : getRootNode()) {treeRootNode buildChildTree(treeRootNode);treeNodes.add(treeRootNode);}return treeNodes;}private FileDir buildChildTree(FileDir pNode) {ListFileDir childTree new ArrayListFileDir();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);//开始解压ListFileObj analysis unZipStrategy.analysis(Files.newInputStream(Paths.get(fileName)));//从解压结果中获取解压文件的全路径ListString list analysis.stream().map(FileObj::getFilePath).collect(Collectors.toList()); // log.info(JSONUtil.toJsonStr(list)); // this.saveFile(analysis, suffix);//根据解压文件的全路径解析出压缩包内文件和目录的树形结构ListFileDir process FileDirProcessor.process(list);FileDirTree fileDirTree new FileDirTree(process);ListFileDir tree fileDirTree.buildTree();log.info(JSONUtil.toJsonStr(tree));} 源码下载 如果想获取完整的示例代码可以从下面这个地址clone: 凡夫贩夫 / unzip-demo · GitCode 写在最后 感谢您阅读我的文章如果您觉得我的内容对您有所启发或帮助欢迎关注我并给我点赞。
http://www.zqtcl.cn/news/717335/

相关文章:

  • 电子商务网站开发视频软件研发过程管理
  • 网站建设实施计划包括wordpress编程视频教程
  • 谈谈你对企业网站的页面设计苏州住房和城乡建设局网站网签
  • 企业建网站服务庆阳网站制作
  • 级a做爰片免费视网站可信赖的南昌网站建设
  • 建立网站需要注意事项做家居用品亚马逊看哪些网站
  • 环影视界免费版wordpress主题优化网站图片
  • 网站开发交付验收文档山西做网站流程步骤
  • 郴州网站seo外包摄影设计素材
  • 平面设计大赛网站给金融的做网站 犯法吗
  • 网站制作需求分析网站建设与 宣传关系
  • 企业网站的推广阶段和特点焦作建设银行门户网站
  • 连云港公司企业网站建设线上平台推广方案
  • 网站维护的协议山东省住房和建设网站
  • 个人网站可以做淘宝客网站建设的公司排名
  • 企业手机网站设计案例做网赌网站怎么推广
  • 2018外贸网站排名购物网站网页设计
  • 赣州培训学做网站软装设计理念
  • 银川建设网站公司wordpress 小工具添加图片
  • 做任务领黄钻的网站怎样建免费个人网站
  • 网站怎么做留言提交功能网站制作公司司
  • 大连购物网站开发wordpress怎么用ftp上传插件
  • 做微商怎样加入网站卖东西赚钱做代理的项目在哪个网站
  • 企业电子商务网站平台建设奉贤做网站公司
  • 非凡网站建设 新三板代运营套餐价格表
  • 湖南建立网站营销设计网站建设的创新之处
  • 手机站是什么意思免费建论坛
  • 网站开发学习路线专用车网站建设哪家好
  • 贵阳网站建设端觉wordpress gif 点击播放
  • 苏州产品推广公司厦门关键词seo