当前位置:   article > 正文

java读取zip/jar包中的文件_java读取zip文件

java读取zip文件

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从文件中读取

  1. private static void readZipFile() {
  2. try (ZipFile zipFile = new ZipFile("/data/testzip.zip");) {
  3. Enumeration<? extends ZipEntry> entries = zipFile.entries();
  4. while(entries.hasMoreElements()){
  5. ZipEntry entry = entries.nextElement();
  6. System.out.println("fileName:"+entry.getName()); //文件名
  7. InputStream stream = zipFile.getInputStream(entry); //读取文件内容
  8. read(stream);
  9. }
  10. } catch(Exception e) {}
  11. //zipFile.close();
  12. }
  13. private static void read(InputStream in) {
  14. try (InputStreamReader reader = new InputStreamReader(in, "UTF-8");
  15. BufferedReader br = new BufferedReader(reader);) {
  16. String con = null;
  17. while ((con = br.readLine()) != null) {
  18. System.out.println(con);
  19. }
  20. } catch (Exception e) {}
  21. }

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

  1. private static InputStream getInputStream() throws FileNotFoundException {
  2. File file = new File("/data/testzip.zip");
  3. InputStream in = new FileInputStream(file);
  4. return in;
  5. }
  6. //错误方法
  7. private static void readZipInputStream() throws FileNotFoundException, IOException {
  8. InputStream zippedIn = getInputStream(); // zip压缩文件流
  9. ZipInputStream zis = new ZipInputStream(zippedIn);
  10. read(zis); //读取的是空
  11. }
  12. //正确方法
  13. private static void readZipInputStream2() throws FileNotFoundException, IOException {
  14. InputStream zipFileInput = getInputStream(); // zip压缩文件流
  15. ZipInputStream zis = new ZipInputStream(zipFileInput);
  16. ZipEntry entry = null;
  17. try {
  18. while ((entry = zis.getNextEntry()) != null) {
  19. try {
  20. final String name = entry.getName();
  21. System.out.println("fileName:"+name);
  22. String content = IOUtils.toString(zis);
  23. System.out.println(content);
  24. } finally {
  25. zis.closeEntry(); // 关闭zipEntry
  26. }
  27. }
  28. } finally {
  29. zis.close(); //关闭zipInputStream
  30. }
  31. }

注意:在从流中读取数据是使用了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

  1. static void test1() {
  2. String path = "/Users/liuxiao/maven-rep/org/apache/thrift/libthrift/0.9.0/libthrift-0.9.0.jar";
  3. try (JarFile jarFile = new JarFile(new File(path));) {
  4. Enumeration<JarEntry> entries = jarFile.entries();
  5. while (entries.hasMoreElements()) {
  6. JarEntry entry = entries.nextElement();
  7. String entryName = entry.getName();
  8. if (!entry.isDirectory() && entryName.equals("org/apache/thrift/TBase.java")) {
  9. System.out.println(entryName);// org/apache/thrift/EncodingUtils.class
  10. read(jarFile.getInputStream(entry));
  11. }
  12. }
  13. } catch (Exception e) {
  14. }
  15. //使用stream api
  16. try (Stream<JarEntry> stream = new JarFile(new File(path)).stream();) {
  17. stream
  18. .filter(entry -> !entry.isDirectory() && entry.getName().endsWith(".class"))
  19. .forEach(entry -> System.out.println(entry.getName()));
  20. } catch(Exception e) {
  21. }
  22. }

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

  1. private static InputStream getJarFileInputStream() throws FileNotFoundException {
  2. File file = new File("/data/mvn_repo/commons-lang/commons-lang/2.1/commons-lang-2.1.jar");
  3. InputStream in = new FileInputStream(file);
  4. return in;
  5. }
  6. private static void readJarInputStream2() throws FileNotFoundException, IOException {
  7. InputStream zipFileInput = getJarFileInputStream(); // jar包流
  8. JarInputStream jis = new JarInputStream(zipFileInput);
  9. JarEntry entry = null;
  10. try {
  11. while ((entry = jis.getNextJarEntry()) != null) {
  12. try {
  13. if (entry.isDirectory()) {
  14. continue;
  15. }
  16. final String name = entry.getName();
  17. System.out.println("fileName:"+name);
  18. String content = IOUtils.toString(jis);
  19. System.out.println(content);
  20. } finally {
  21. jis.closeEntry(); // 关闭zipEntry
  22. }
  23. }
  24. } finally {
  25. jis.close(); //关闭zipInputStream
  26. }
  27. }

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

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

总结:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/37548
推荐阅读
相关标签
  

闽ICP备14008679号