java读取zip/jar包中的文件

2023-11-07

1、jar vs zip:

jar 文件和 zip 文件都是归档文件,并且都经过压缩。事实上,jar 文件使用与 zip 文件相同的存档和压缩技术,所以 jar 文件实际上是一种特定类型的 zip 文件。(JAR 文件本质上是一个包含可选 META-INF 目录的 zip 文件。)这一切都意味着:

  • 您可以使用与打开 zip 文件相同的工具打开 jar 文件
  • jar 文件是 zip 文件的子集,因此如果 zip 文件遵循 jar 规范,则它可以用作 jar 文件

2、读取zip压缩文件:

1)方法一:通过ZipFile从文件中读取

private static void readZipFile() {
    try (ZipFile zipFile = new ZipFile("/data/testzip.zip");) {
	    Enumeration<? extends ZipEntry> entries = zipFile.entries();
         while(entries.hasMoreElements()){
             ZipEntry entry = entries.nextElement();
		 System.out.println("fileName:"+entry.getName()); //文件名
		 InputStream stream = zipFile.getInputStream(entry); //读取文件内容
		 read(stream);
         }
    } catch(Exception e) {}
	//zipFile.close();
}
private static void read(InputStream in) { 
    try (InputStreamReader reader = new InputStreamReader(in, "UTF-8");
         BufferedReader br = new BufferedReader(reader);) {
         String con = null;
	      while ((con = br.readLine()) != null) {
	          System.out.println(con);
	      }
    } catch (Exception e) {}
}

2)方法二:通过ZipInputStream从流中读取

private static InputStream getInputStream() throws FileNotFoundException {
	File file = new File("/data/testzip.zip");
	InputStream in = new FileInputStream(file);
	return in;
}
//错误方法
private static void readZipInputStream() throws FileNotFoundException, IOException {
	InputStream zippedIn = getInputStream(); // zip压缩文件流
	ZipInputStream zis = new ZipInputStream(zippedIn);
	read(zis); //读取的是空
}
//正确方法
private static void readZipInputStream2() throws FileNotFoundException, IOException {
	InputStream zipFileInput = getInputStream(); // zip压缩文件流
	ZipInputStream zis = new ZipInputStream(zipFileInput);
	ZipEntry entry = null;
	try {
		while ((entry = zis.getNextEntry()) != null) {
			try {
				final String name = entry.getName();
				System.out.println("fileName:"+name);
				String content = IOUtils.toString(zis);
				System.out.println(content);
			} finally {
				zis.closeEntry(); // 关闭zipEntry
			}
		}
	} finally {
		zis.close(); //关闭zipInputStream
	}
}

注意:在从流中读取数据是使用了IOUtils,原因是自定义read方法读取完后会把传递进来的inputStream给关闭了。如果zip包中有多个文件,那么在读取第二个entry文件时就会报错。zipInputStream只能在最后关闭。而IOUtils使用了copy的方式,不会关闭传入的流

3、jar中文件/目录便利,以及读取:

1)方法一:使用JarFile读取Jar文件

和ZipFile类似,使用'getEntry(String name)'或'entires'获得ZipEntry或JarEntry(它们可以看作同一东西),接下来使用" JarFile.getInputStream(ZipEntry ze)"将其用于获取InputStream

static void test1() {
    String path = "/Users/liuxiao/maven-rep/org/apache/thrift/libthrift/0.9.0/libthrift-0.9.0.jar";
    try (JarFile jarFile = new JarFile(new File(path));) {
        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            String entryName = entry.getName();
            if (!entry.isDirectory() && entryName.equals("org/apache/thrift/TBase.java")) {
                System.out.println(entryName);//  org/apache/thrift/EncodingUtils.class
                read(jarFile.getInputStream(entry));
            }
        }
    } catch (Exception e) {
    }
    //使用stream api
try (Stream<JarEntry> stream = new JarFile(new File(path)).stream();) {
        stream
            .filter(entry -> !entry.isDirectory() && entry.getName().endsWith(".class"))
            .forEach(entry -> System.out.println(entry.getName()));
    } catch(Exception e) {
    }
}

2)方法二:通过JarInputStream从流中读取(和ZipInputStream类似)

private static InputStream getJarFileInputStream() throws FileNotFoundException {
	File file = new File("/data/mvn_repo/commons-lang/commons-lang/2.1/commons-lang-2.1.jar");
	InputStream in = new FileInputStream(file);
	return in;
}
private static void readJarInputStream2() throws FileNotFoundException, IOException {
	InputStream zipFileInput = getJarFileInputStream(); // jar包流
	JarInputStream jis = new JarInputStream(zipFileInput);
	JarEntry entry = null;
	try {
		while ((entry = jis.getNextJarEntry()) != null) {
			try {
				if (entry.isDirectory()) {
					continue;
				}
				final String name = entry.getName();
				System.out.println("fileName:"+name);
				String content = IOUtils.toString(jis);
				System.out.println(content);
			} finally {
				jis.closeEntry(); // 关闭zipEntry
			}
		}
	} finally {
		jis.close(); //关闭zipInputStream
	}
}

3)方法三:通过JarURLConnection来打开一个jar中的资源,然后通过流来读取 

static void test2() throws Exception {
	String filePath = "/Users/liuxiao/maven-rep/org/apache/thrift/libthrift/0.9.0/libthrift-0.9.0.jar";
	String name = "org/apache/thrift/TBase.java";
	
	URL url = new URL("jar:file:" + filePath + "!/" + name);
	JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
	try (InputStream in = jarConnection.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));) {
		String con = null;
		while ((con = br.readLine()) != null) {
			System.out.println(con);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

总结:

由于zip和jar结构时一致的,所以ZipFile和JarFile,ZipInputStream和JarInputStream的使用方法是一样的。需要说明的一点是,由于zip包的这种特殊结构,默认ZipInputStream中是不包含数据的,只有在调用getNextEntry方法后,才回把对应的entry(zip包中的一个文件)内容写入到ZipInputStream中。上面的一个错误写法中,可以看到直接从ZipInputStream中读不到数据,只有调用getNextEntry后才可以。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java读取zip/jar包中的文件 的相关文章

随机推荐

  • cuda C++ cmake makefile

    https blog csdn net u011679999 article details 80041081 spm 1001 2014 3001 5502 https blog csdn net comedate article det
  • 控制微信公众号物理键返回url

    总有一些奇葩的需求 在公众号中 如果你写的模块是一个公众号的子模块 那么当你在模块的第一级时 再点返回 应该是返回到公众号的主页 也就是模块区域 而不是返回你上一个地址 直接上代码 1 先监听到物理返回键 在mounted钩子定义 再去de
  • C++ 左值、右值、右值引用

    C 左值 右值 右值引用 发表于2016 2 3 15 49 35 98人阅读 分类 C 在C语言中 我们常常会提起左值 lvalue 右值 rvalue 这样的称呼 而在编译程序时 编译器有时也会在报出的错误信息中会包含左值 右值的说法
  • C++ 中有符号数转化为无符号数

    1 背景知识 我的计算中 char 类型占 8 个比特位 unsigned char 类型能表示的数的范围为 0 2 8 1 即 0 255 共 256 个数 int 类型占 32 个比特位 那么 unsigned 类型所能表示的数的范围为
  • STM32:配置定时器为PWM输出模式以及编码器接口模式

    一 STM32的高级定时器TIM8配置为PWM输出模式 最近在工程项目中 需要用stm32的定时器 以高级定时器TIM8为例 产生两路PWM输出 作为电机的pwm输入 方法如下 初始化电机控制所需IO口 void Motor Init vo
  • Linux——(管道练习)C实现父子进程通信、兄弟进程通信、多个读写端操作管道及管道缓冲区大小、fifo实现非血缘间进程通信

    一 父子进程通信 lswc l 父进程ls写到管道 子进程wc管道的内容 父进程创建管道 拥有读写两端 父进程fork子进程 父进程要将原本输出到屏幕上的内容输出到管道中 用dup实现 然后execlp去进行ls操作 子进程同理 将原本从标
  • 毕业设计-基于轨道的扣件状态检测- YOLO

    目录 前言 课题背景和意义 实现技术思路 一 YOLO 网络结构 二 模型建立 三 实验结果 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年
  • BUG收割机之解决eureka的Application显示为UNKNOWN

    BUG收割机之解决eureka的Application显示为UNKNOWN 初学spring cloud的小伙伴们 肯定会遇到eureka服务的application显示为UNKNOWN的情况 如果不幸和下图中的BUG类似 那么就请继续阅读
  • Metasploit超详细安装及使用教程(图文版)

    通过本篇文章 我们将会学习以下内容 1 在Windows上安装Metasploit 2 在Linux和MacOS上安装Metasploit 3 在Kali Linux中使用 Metasploit 4 升级Kali Linux 5 使用虚拟化
  • Python Pandas –数据输入和输出

    Pandas as a library can read and write data to a wide variety of sources In this article we would concentrate on the fol
  • 【衍射光栅】用于Matlab的交互式衍射光栅模型研究

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 干涉和衍射的交互式仿真 2 2 衍射光栅光谱 2 3 一阶衍射的扩展视图 2 4 用
  • Linux修改文件句柄数及vm.max_map_count、stack size

    一 修改文件句柄数 1 1 查看当前大小 ulimit a 1 2 临时修改 ulimit n 4096 1 3 永久修改 vim etc security limits conf soft nofile 65536 hard nofile
  • Python爬虫完整代码,一人一份,随便拿~

    对于新手做Python爬虫来说是有点难处的 前期练习的时候可以直接套用模板 这样省时省力还很方便 使用Python爬取某网站的相关数据 并保存到同目录下Excel 直接上代码 import re import urllib error im
  • 达梦数据库-锁表

    查询锁表语句 select from v sessions where trx id in select trx id from V LOCK and user name 用户名称 order by create time desc 关闭会
  • Aspose_Diagram_ for Java 2020.X.最先进的全新版

    Java 20 4的Aspose Diagram Java的Aspose Diagram是强大的Microsoft Visio文档处理API 它提供了常见的功能 例如创建 解析和转换本机Visio格式 并支持一些常用的图像和固定布局格式 应
  • 机器学习K-均值——nonzero(clusterAssment[冒号,0].A==cent

    先准备测试数据 如下 上面都是准备数据 下面才是一步步的告诉你怎么生成我们要的数据 矩阵 A是把矩阵转换为数组numpy nonzero 返回哪些元素不是False或者0 第一个array描述行 第二个array描述列
  • 敏捷虽好勿盲从

    原文作者 MARK LEVISON 很多公司正在往陷阱里掉 常常表现为 我们的合作伙伴 或竞争对手 采用了敏捷 因此我们也需要采用敏捷 如果没有正当的理由就向敏捷转型 组织将会受到伤害 就这么简单 多说无益 在20世纪80 90年代 制造商
  • 2022-05-08 Unity核心5——Tilemap

    文章目录 一 瓦片资源 二 瓦片调色板窗口 三 瓦片地图关键脚本和碰撞器 四 导入瓦片官方拓展包 五 新增瓦片类型 六 新增笔刷类型 七 代码管理 Tilemap Tilemap 一般称之为瓦片地图或者平铺地图 是 Unity2017 中新
  • java.lang.RuntimeException: com.mysql.cj.exceptions.CJException: Unknown database ‘test‘

    后端小白在进行IDEA数据库连接的时候会进行以下报错 这是没有mysql驱动的问题 填错了就会报以下的错误哦 解决方法 在URL后面添加 serverTimezone GMT
  • java读取zip/jar包中的文件

    1 jar vs zip jar 文件和 zip 文件都是归档文件 并且都经过压缩 事实上 jar 文件使用与 zip 文件相同的存档和压缩技术 所以 jar 文件实际上是一种特定类型的 zip 文件 JAR 文件本质上是一个包含可选 ME