Java lee los archivos en el paquete zip/jar

1.jar frente a zip:

Tanto los archivos jar como los zip son archivos de almacenamiento y ambos están comprimidos. De hecho, los archivos jar utilizan las mismas técnicas de archivo y compresión que los archivos zip, por lo que los archivos jar son en realidad un tipo específico de archivo zip. (Un archivo JAR es esencialmente un archivo zip que contiene un directorio META-INF opcional). Todo esto significa:

  • Puede abrir archivos jar con las mismas herramientas que usa para abrir archivos zip
  • Los archivos jar son un subconjunto de archivos zip, por lo que un archivo zip se puede utilizar como archivo jar si sigue la especificación jar.

2. Lea el archivo comprimido zip:

1) Método 1: leer el archivo a través de 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) Método 2: leer de la transmisión a través de 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
	}
}

Nota : IOUtils se utiliza para leer datos de la secuencia, porque el método de lectura personalizado cerrará la secuencia de entrada pasada después de la lectura. Si hay varios archivos en el paquete zip, se informará un error al leer el segundo archivo de entrada. zipInputStream solo se puede cerrar al final. Sin embargo, IOUtils utiliza el método de copia y no cierra la transmisión entrante .

3. Los archivos/directorios en el jar son convenientes y leen:

1) Método 1: use JarFile para leer el archivo Jar

De manera similar a ZipFile, use 'getEntry(String name)' o 'enteres' para obtener ZipEntry o JarEntry (pueden considerarse lo mismo) y luego use "JarFile.getInputStream(ZipEntry ze)" para obtener 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) Método 2: leer de la transmisión a través de JarInputStream (similar a 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) Método 3: abra un recurso en un jar a través de JarURLConnection y luego léalo a través de la secuencia 

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();
	}
}

Resumir:

Dado que las estructuras zip y jar son consistentes, el uso de ZipFile y JarFile, ZipInputStream y JarInputStream es el mismo. Cabe señalar que debido a la estructura especial del paquete zip, el ZipInputStream predeterminado no contiene datos y solo después de llamar al método getNextEntry, el contenido de la entrada correspondiente (un archivo en el paquete zip) se escribe en ZipInputStream. medio. En la escritura incorrecta anterior, puede ver que los datos no se pueden leer directamente desde ZipInputStream, solo después de llamar a getNextEntry.

Supongo que te gusta

Origin blog.csdn.net/liuxiao723846/article/details/130967940
Recomendado
Clasificación