在Java 8中使用Stream API列出ZIP文件的内容

在Java 8 java.util.zip.ZipFile配备了stream方法,该方法可以非常轻松地浏览ZIP文件条目。 在此博客文章中,我将展示许多示例,这些示例显示了我们可以如何快速浏览ZIP文件条目。

注意:就本博客而言,我将一个GitHub存储库下载为ZIP文件,并将其复制到c:/tmp

Java 7之前的版本

在Java 7之前的Java中读取ZIP文件条目有点麻烦……难道是吗? 这是在查看以下代码时开始讨厌Java的方式:

public class Zipper {public void printEntries(PrintStream stream, String zip)  {ZipFile zipFile = null;try {zipFile = new ZipFile(zip);Enumeration<? extends ZipEntry> entries = zipFile.entries();while (entries.hasMoreElements()) {ZipEntry zipEntry = entries.nextElement();stream.println(zipEntry.getName());}} catch (IOException e) {// error while opening a ZIP file} finally {if (zipFile != null) {try {zipFile.close();} catch (IOException e) {// do something}}}}
}

Java 7

使用Java 7,这可以简单得多–感谢try-with-resources但是我们仍然被“强制”使用Enumeration来浏览ZIP文件条目:

public class Zipper {public void printEntries(PrintStream stream, String zip) {try (ZipFile zipFile = new ZipFile(zip)) {Enumeration<? extends ZipEntry> entries = zipFile.entries();while (entries.hasMoreElements()) {ZipEntry zipEntry = entries.nextElement();stream.println(zipEntry.getName());}} catch (IOException e) {// error while opening a ZIP file}}
}

使用流API

真正的乐趣始于Java8。从Java 8开始, java.util.zip.ZipFile具有一个新的方法stream ,该方法流通过ZIP文件条目返回有序流。 在使用Java处理ZIP文件时,这提供了很多机会。 前面的示例可以用Java 8如下编写:

public class Zipper {public void printEntries(PrintStream stream, String zip) {try (ZipFile zipFile = new ZipFile(zip)) {zipFile.stream().forEach(stream::println);} catch (IOException e) {// error while opening a ZIP file}}
}

借助Stream API,我们可以通过多种方式ZipFile 。 见下文…

过滤和排序ZIP文件内容

public void printEntries(PrintStream stream, String zip) {try (ZipFile zipFile = new ZipFile(zip)) {Predicate<ZipEntry> isFile = ze -> !ze.isDirectory();Predicate<ZipEntry> isJava = ze -> ze.getName().matches(".*java");Comparator<ZipEntry> bySize = (ze1, ze2) -> Long.valueOf(ze2.getSize() - ze1.getSize()).intValue();zipFile.stream().filter(isFile.and(isJava)).sorted(bySize).forEach(ze -> print(stream, ze));} catch (IOException e) {// error while opening a ZIP file}
}private void print(PrintStream stream, ZipEntry zipEntry) {stream.println(zipEntry.getName() + ", size = " + zipEntry.getSize());
}

遍历ZIP条目时,我检查该条目是否为文件,并且是否与给定名称匹配(为简单起见,在本示例中进行了编码),然后使用给定的比较器按大小对它进行排序。

创建ZIP文件的文件索引

在此示例中,我按文件名的首字母对ZIP条目进行分组,以创建Map<String, List<ZipEntry>>索引。 预期结果应类似于以下内容:

a = [someFile/starting/with/an/A]
u = [someFile/starting/with/an/U, someOtherFile/starting/with/an/U]

同样,使用Stream API确实很容易:

public void printEntries(PrintStream stream, String zip) {try (ZipFile zipFile = new ZipFile(zip)) {Predicate<ZipEntry> isFile = ze -> !ze.isDirectory();Predicate<ZipEntry> isJava = ze -> ze.getName().matches(".*java");Comparator<ZipEntry> bySize =(ze1, ze2) -> Long.valueOf(ze2.getSize()).compareTo(Long.valueOf(ze1.getSize()));Map<String, List<ZipEntry>> result = zipFile.stream().filter(isFile.and(isJava)).sorted(bySize).collect(groupingBy(this::fileIndex));result.entrySet().stream().forEach(stream::println);} catch (IOException e) {// error while opening a ZIP file}
}private String fileIndex(ZipEntry zipEntry) {Path path = Paths.get(zipEntry.getName());Path fileName = path.getFileName();return fileName.toString().substring(0, 1).toLowerCase();
}

在ZIP文件条目中查找文本

在最后一个示例中,我在所有带有java扩展名的文件中搜索@Test文本出现的地方。 这次,我将利用BufferedReaderlines方法返回行流。

public void printEntries(PrintStream stream, String zip) {try (ZipFile zipFile = new ZipFile(zip)) {Predicate<ZipEntry> isFile = ze -> !ze.isDirectory();Predicate<ZipEntry> isJava = ze -> ze.getName().matches(".*java");List<ZipEntry> result = zipFile.stream().filter(isFile.and(isJava)).filter(ze -> containsText(zipFile, ze, "@Test")).collect(Collectors.toList());result.forEach(stream::println);} catch (IOException e) {// error while opening a ZIP file}
}private boolean containsText(ZipFile zipFile, ZipEntry zipEntry, String needle) {try (InputStream inputStream = zipFile.getInputStream(zipEntry);BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {Optional<String> found = reader.lines().filter(l -> l.contains(needle)).findFirst();return found.isPresent();} catch (IOException e) {return false;}
}

摘要

Java 8中的Stream API是一种功能强大的解决方案,可帮助轻松解决相对简单的任务。 我认为这就是它的力量。

本文中提供的示例相对简单,它们仅为可视化目的而创建。 但我希望您喜欢它们并发现它们有用。

资源资源

  • http://docs.oracle.com/javase/tutorial/index.html

翻译自: https://www.javacodegeeks.com/2014/06/listing-a-zip-file-contents-with-stream-api-in-java-8.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法...

tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 【标 题】&#xff1a;tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法【关键字】&#xff1a;tomcat5,jsp,getOutpu…

Web API应用架构设计分析(1)

Web API 是一种应用接口框架&#xff0c;它能够构建HTTP服务以支撑更广泛的客户端&#xff08;包括浏览器&#xff0c;手机和平板电脑等移动设备&#xff09;的框架&#xff0c; ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台。本文主要以AS…

记手机端 下拉加载新数据

$(#container).unbind("scroll").bind(scroll,function(e){var sum this.scrollHeight - 5;console.log(sum)console.log($(this).scrollTop() $(this).height())if(sum <$(this).scrollTop() $(this).height()){ getmore();       }     }) $(#co…

一个切图仔的 CSS 笔记

1&#xff0c;flexbox~注意&#xff0c;设为 Flex 布局以后&#xff0c;子元素的float、clear和vertical-align属性将失效。 在ios8上要加上前缀 display: -webkit-box; display: -webkit-flex; display: -webkit-box; /* Chrome 4, Safari 3.1, iOS Safari 3.2 */ display: …

如何使用JPA Type Converter加密数据

几天前&#xff0c;我读了Bear Giles关于2012年使用JPA监听器进行数据库加密的有趣文章。他讨论了对加密解决方案的要求&#xff0c;并提供了JPA监听器的代码示例。 他的主要要求是&#xff1a; 提供不影响应用程序的透明加密&#xff0c; 能够在部署时添加加密&#xff0c; …

go语言的排序和去重

go语言的排序&#xff1a; https://blog.csdn.net/u010983881/article/details/52460998 go语言去重&#xff1a; https://blog.csdn.net/qq_27068845/article/details/77407358 通过构造set去重&#xff08;go中没有set&#xff09;&#xff1a; https://studygolang.com/arti…

MapXtreme2008中操作矢量符号和定制符号

本文部分说明内容摘自网络文章&#xff0c;经过本人在MapXtreme2008中编写相关的演示例子&#xff0c;详细说明如何操作MapXtreme2008提供的矢量符号和定制符号。 MapXtreme 在其安装过程中自动安装 10 种 MapInfo 特定的 TrueType 字体。这些字体为用户提供了字形符号选择&am…

指甲之指甲长期没有甲半月弧(二)

中医的精是构成人体的基本物质。精来源于先天的禀赋及后天饮食营养。中医认为&#xff0c;气不耗归于肝为血&#xff0c;血不耗归于肾为精&#xff0c;精不耗归于骨为髓。 半月痕正是人体精髓的窗口。而半月痕的变化&#xff0c;犹如汽车上的油表一样&#xff0c;它会告颂人体&…

编写干净的测试–从配置开始

很难为干净的代码找到一个好的定义&#xff0c;因为我们每个人都有自己的单词clean的定义。 但是&#xff0c;有一个似乎是通用的定义&#xff1a; 干净的代码易于阅读。 这可能会让您感到有些惊讶&#xff0c;但是我认为该定义也适用于测试代码。 使测试尽可能具有可读性是我…

集合类(二)

关于迭代器&#xff08;Iterator&#xff09;的两种迭代机制&#xff1a;fail-fast 和 fail-safe fail-fast 机制&#xff1a;遍历集合时&#xff0c;当集合结构被修改&#xff0c;会抛出Concurrent Modification Exception 触发条件&#xff1a;单线程在遍历过程修改&#xff…

jQuery-弹幕

该方法可能有bug&#xff0c;毕竟简单粗暴 <!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title></title> <script type"text/javascript" src"js/jquery-1.11.0.js"></script> <s…

ubuntu下C编程,编译基础( 转)

buntu下C编程&#xff0c;编译基础 C 编程中相关文件后缀 .a静态库 (archive).cC源代码&#xff08;需要编译预处理&#xff09;.hC源代码头文件.iC源代码&#xff08;不需编译预处理&#xff09;.o对象文件.s汇编语言代码.so动态库单个源文件生成可执行程序 下面是一个简单的…

转载:97特瑞心得

单位里无聊打着玩的心得&#xff0c;写了段时间了&#xff0c;基本是哪天想到什么就打上去&#xff0c;狗屁不通的地方请大家包涵。97特瑞玩了有10年多了吧,97刚出来的时候就玩的特瑞&#xff0c;别人都八神&#xff0c;萝卜特&#xff0c;克拉克的时代我就坚持用特瑞&#xff…

Hibernate二级/查询缓存的陷阱

这篇文章将介绍如何设置Hibernate二级和查询缓存&#xff0c;它们如何工作以及最常见的陷阱。 休眠二级缓存是用于存储实体数据的应用程序级缓存。 查询缓存是一个单独的缓存&#xff0c;仅存储查询结果。 这两个缓存实际上是并存的&#xff0c;因为在很多情况下&#xff0c;…

C#工厂模式-简单工厂

简单工厂: 工厂模式:简单工厂,工厂方法,抽象工厂三种. 简单工厂(力求简洁) 工厂即为生产东西的地方.在C#也有这种模式,充分利用了面向对象语言的三大特征(多态,继承),简单工厂.工厂的功能就是生产,而生产些什么呢?一个工厂可以生产鞋子,生产衣服.它们所处的车间不一样,所以需…

跨域方式

原文地址&#xff1a;https://www.xingkongbj.com/blog/http/cross-origin.html http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html document.domain iframe 实现父页面与其内部 iframe 页面通讯&#xff0c;要求一级域名相同两个页面设置 document.domain 为相…

Linux学习之四——磁盘与文件系统管理

一、一些基本定义 1. superblock&#xff1a;记录此 filesystem 的整体信息&#xff0c;包括inode/block的总量、使用量、剩余量&#xff0c; 以及文件系统的格式与相关信息等&#xff1b;2. inode&#xff1a;记录档案的属性&#xff0c;一个档案占用一个inode&#xff0c;同时…

使用.Net 1.1的项目,TreeView控件不能正常显示

使用.Net 1.1的项目&#xff0c;TreeView控件不能正常显示&#xff0c;往往是显示一大堆的文字&#xff0c;那是因为脚本没有被执行造成的&#xff0c;需要在web.config里配置一下。<!-- Microsoft WebControls --><MicrosoftWebControls> <add key"Common…

吸气剂/设定者。 邪恶。 期。

从2003年开始&#xff0c;艾伦霍鲁布&#xff08;Allen Holub&#xff09;讨论了为什么吸气剂和塞特方法是邪恶的著名文章&#xff0c;关于吸气剂/塞特方法是否是反模式&#xff0c;应该避免使用&#xff0c;还是我们在面向对象中不可避免地需要它&#xff0c;这是一个古老的争…

你不可不知的数据库northwind

说起northwind&#xff0c;40左右的大年一定不会陌生&#xff0c;它是著名的northwind示例库&#xff0c;在SQL Server 是标配。 它有8张表&#xff0c;涉及客户、商品、订单。 如果你是有志从事企业级应用开发&#xff0c;或有志从事企业互联网开发&#xff0c;一定不要错过no…