在Java 8中使用Stream API列出ZIP文件的内容
在Java 8 java.util.zip.ZipFile配備了stream方法,該方法可以非常輕松地瀏覽ZIP文件條目。 在此博客文章中,我將展示許多示例,這些示例顯示了我們可以如何快速瀏覽ZIP文件條目。
注意:就本博客而言,我將一個(gè)GitHub存儲庫下載為ZIP文件,并將其復(fù)制到c:/tmp 。
Java 7之前的版本
在Java 7之前的Java中讀取ZIP文件條目有點(diǎn)麻煩……難道是嗎? 這是在查看以下代碼時(shí)開始討厭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但是我們?nèi)匀槐弧皬?qiáng)制”使用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具有一個(gè)新的方法stream ,該方法流通過ZIP文件條目返回有序流。 在使用Java處理ZIP文件時(shí),這提供了很多機(jī)會(huì)。 前面的示例可以用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文件內(nèi)容
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條目時(shí),我檢查該條目是否為文件,并且是否與給定名稱匹配(為簡單起見,在本示例中進(jìn)行了編碼),然后使用給定的比較器按大小對它進(jìn)行排序。
創(chuàng)建ZIP文件的文件索引
在此示例中,我按文件名的首字母對ZIP條目進(jìn)行分組,以創(chuàng)建Map<String, List<ZipEntry>>索引。 預(yù)期結(jié)果應(yīng)類似于以下內(nèi)容:
a = [someFile/starting/with/an/A] u = [someFile/starting/with/an/U, someOtherFile/starting/with/an/U]同樣,使用Stream API確實(shí)很容易:
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文件條目中查找文本
在最后一個(gè)示例中,我在所有帶有java擴(kuò)展名的文件中搜索@Test文本出現(xiàn)的地方。 這次,我將利用BufferedReader的lines方法返回行流。
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是一種功能強(qiáng)大的解決方案,可幫助輕松解決相對簡單的任務(wù)。 我認(rèn)為這就是它的力量。
本文中提供的示例相對簡單,它們僅為可視化目的而創(chuàng)建。 但我希望您喜歡它們并發(fā)現(xiàn)它們有用。
資源資源
- 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
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的在Java 8中使用Stream API列出ZIP文件的内容的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么叫图像压缩比 图像压缩比的解释
- 下一篇: 寅年是哪一年 什么年份