Java中的ZIP标准
这样一篇入门级文章,实在没有多大技术含量,只是碰巧刚才有人问我如何读EAR或者WAR中的某个资源文件,最简单的方式以资源方式读取,另外一种则可以采用Zip API去读,实际上J2EE中我们接触到的全部部署文件都是遵循ZIP压缩标准的。明白这一点,我们就不用关注他的文件扩展名到底是什么,都可以方便的用WinZip或者WinRAR去查看其压缩包的内容。同时我们在部署一些应用时,如果我们熟悉了EAR、WAR的结构规则,我们也可以直接按照其目录结构规则用WinZip或者WinRAR组织发布的压缩文件,而不用ANT(哈哈,不是推荐替换ANT,只是让初学者可以多一条路径来理解这个过程)。下面我给出这两种方式的实现。
第一种方式,通过classloader,将zip格式中的文件当做资源来处理,提供读取每个资源的InputStream,得到这个InputStream对象我们就可以象操作普通文件一样的操作了。
package rookie.demo;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* @description 演示如何读取EAR,WAR,JAR中的资源文件。
*/
public class ResourceDemo {
public static void main(String[] args) {
if (args.length < 1) {
usage();
return;
}
try {
ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
BufferedReader reader = new BufferedReader(new InputStreamReader(clsLoader.getResourceAsStream(args[0])));
String sLine;
while ((sLine = reader.readLine()) != null) {
System.out.println(sLine);
}
reader.close();
} catch (IOException exp) {
exp.printStackTrace();
}
}
/**
* @description Show usage information
*/
public static void usage() {
System.out.println("=======================================================================");
System.out.println(" Usage: ");
System.out.println(" java rookie.demo.ResourceDemo resourceName");
System.out.println("");
System.out.println("=======================================================================");
}
};
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* @description 演示如何读取EAR,WAR,JAR中的资源文件。
*/
public class ResourceDemo {
public static void main(String[] args) {
if (args.length < 1) {
usage();
return;
}
try {
ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
BufferedReader reader = new BufferedReader(new InputStreamReader(clsLoader.getResourceAsStream(args[0])));
String sLine;
while ((sLine = reader.readLine()) != null) {
System.out.println(sLine);
}
reader.close();
} catch (IOException exp) {
exp.printStackTrace();
}
}
/**
* @description Show usage information
*/
public static void usage() {
System.out.println("=======================================================================");
System.out.println(" Usage: ");
System.out.println(" java rookie.demo.ResourceDemo resourceName");
System.out.println("");
System.out.println("=======================================================================");
}
};
第二种方式,我们使用java.util.zip包提供的api进行文件操作,这个例子给出了简单的ZipEntry列表及读取功能。
package rookie.demo;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.*;
/**
* @description 演示如何读取Zip文件,Zip作为Java压缩格式的标准,事实上我们所见的EAR,WAR,JAR都是Zip格式的压缩文件。
*/
public class ZipDemo {
String sFileName;
public ZipDemo(String fName) {
sFileName = fName;
}
public void setFileName(String fName) {
sFileName = fName;
}
public String getFileName() {
return sFileName;
}
/**
* @description List the zip file's entries
*/
public void listEntries()
throws Exception {
if (sFileName == null || sFileName == ""){
throw new Exception("Have not specified the zip file name.");
}
ZipFile zFile = new ZipFile(sFileName);
for (Enumeration e = zFile.entries() ; e.hasMoreElements() ;) {
ZipEntry zEntry = (ZipEntry)e.nextElement();
System.out.println(zEntry.getName());
}
zFile.close();
}
/**
* @description Read the specified entry
* @param sEntry the name of the entry for reading
*/
public void readEntry(String sEntry)
throws Exception {
if (sFileName == null || sFileName == ""){
throw new Exception("Have not specified the zip file name.");
}
ZipFile zFile = new ZipFile(sFileName);
ZipEntry zEntry = zFile.getEntry(sEntry);
BufferedReader reader = new BufferedReader(new InputStreamReader(zFile.getInputStream(zEntry)));
String sLine;
while ((sLine = reader.readLine()) != null){
System.out.println(sLine);
}
reader.close();
zFile.close();
}
public static void main(String[] args) {
if (args.length < 1) {
usage();
return;
}
ZipDemo demo = new ZipDemo(args[0]);
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String sLine;
while ((sLine = reader.readLine()) != null && !sLine.equalsIgnoreCase("exit") && !sLine.equalsIgnoreCase("quit")){
try {
if (sLine.equalsIgnoreCase("help")){
System.out.println("help\tShow this command list information.");
System.out.println("list\tList the zip file entries.");
System.out.println("read <entry>\tRead the specified zip file entry content.");
System.out.println("open <zipfile>\tSpecify the operating zip file name.");
System.out.println("name\tShow the current operating zip file name.");
} else if (sLine.equalsIgnoreCase("list")){
demo.listEntries();
} else if (sLine.equalsIgnoreCase("name")){
System.out.println(demo.getFileName());
} else if (sLine.substring(0, 5).equalsIgnoreCase("read ")) {
demo.readEntry(sLine.substring(5));
} else if (sLine.substring(0, 5).equalsIgnoreCase("open ")) {
demo.setFileName(sLine.substring(5));
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
reader.close();
} catch (IOException exp) {
exp.printStackTrace();
}
}
/**
* @description Show usage information
*/
public static void usage() {
System.out.println("=======================================================================");
System.out.println(" Usage: ");
System.out.println(" java rookie.demo.ZipDemo zipFile");
System.out.println("");
System.out.println("=======================================================================");
}
};
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.*;
/**
* @description 演示如何读取Zip文件,Zip作为Java压缩格式的标准,事实上我们所见的EAR,WAR,JAR都是Zip格式的压缩文件。
*/
public class ZipDemo {
String sFileName;
public ZipDemo(String fName) {
sFileName = fName;
}
public void setFileName(String fName) {
sFileName = fName;
}
public String getFileName() {
return sFileName;
}
/**
* @description List the zip file's entries
*/
public void listEntries()
throws Exception {
if (sFileName == null || sFileName == ""){
throw new Exception("Have not specified the zip file name.");
}
ZipFile zFile = new ZipFile(sFileName);
for (Enumeration e = zFile.entries() ; e.hasMoreElements() ;) {
ZipEntry zEntry = (ZipEntry)e.nextElement();
System.out.println(zEntry.getName());
}
zFile.close();
}
/**
* @description Read the specified entry
* @param sEntry the name of the entry for reading
*/
public void readEntry(String sEntry)
throws Exception {
if (sFileName == null || sFileName == ""){
throw new Exception("Have not specified the zip file name.");
}
ZipFile zFile = new ZipFile(sFileName);
ZipEntry zEntry = zFile.getEntry(sEntry);
BufferedReader reader = new BufferedReader(new InputStreamReader(zFile.getInputStream(zEntry)));
String sLine;
while ((sLine = reader.readLine()) != null){
System.out.println(sLine);
}
reader.close();
zFile.close();
}
public static void main(String[] args) {
if (args.length < 1) {
usage();
return;
}
ZipDemo demo = new ZipDemo(args[0]);
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String sLine;
while ((sLine = reader.readLine()) != null && !sLine.equalsIgnoreCase("exit") && !sLine.equalsIgnoreCase("quit")){
try {
if (sLine.equalsIgnoreCase("help")){
System.out.println("help\tShow this command list information.");
System.out.println("list\tList the zip file entries.");
System.out.println("read <entry>\tRead the specified zip file entry content.");
System.out.println("open <zipfile>\tSpecify the operating zip file name.");
System.out.println("name\tShow the current operating zip file name.");
} else if (sLine.equalsIgnoreCase("list")){
demo.listEntries();
} else if (sLine.equalsIgnoreCase("name")){
System.out.println(demo.getFileName());
} else if (sLine.substring(0, 5).equalsIgnoreCase("read ")) {
demo.readEntry(sLine.substring(5));
} else if (sLine.substring(0, 5).equalsIgnoreCase("open ")) {
demo.setFileName(sLine.substring(5));
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
reader.close();
} catch (IOException exp) {
exp.printStackTrace();
}
}
/**
* @description Show usage information
*/
public static void usage() {
System.out.println("=======================================================================");
System.out.println(" Usage: ");
System.out.println(" java rookie.demo.ZipDemo zipFile");
System.out.println("");
System.out.println("=======================================================================");
}
};
最后补充下,内容如何写入,下例是写入一个文本文件
package rookie.demo;
import java.io.*;
import java.util.zip.*;
public class WriteZip {
public static void main(String[] args) {
if (args.length < 1){
System.out.println("java rookie.demo.WriteZip zipfile");
return;
}
try {
ZipEntry zEntry = new ZipEntry("WEB-INF/web.xml");
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(args[0]));
zos.putNextEntry(zEntry);
PrintWriter writer = new PrintWriter(zos);
writer.println("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
writer.println("<web-app>");
writer.println("</web-app>");
writer.close();
zos.close();
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
import java.io.*;
import java.util.zip.*;
public class WriteZip {
public static void main(String[] args) {
if (args.length < 1){
System.out.println("java rookie.demo.WriteZip zipfile");
return;
}
try {
ZipEntry zEntry = new ZipEntry("WEB-INF/web.xml");
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(args[0]));
zos.putNextEntry(zEntry);
PrintWriter writer = new PrintWriter(zos);
writer.println("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
writer.println("<web-app>");
writer.println("</web-app>");
writer.close();
zos.close();
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
更新包中某一个文件,下面更新一个文本文件
package rookie.demo;
import java.io.*;
import java.util.*;
import java.util.zip.*;
public class PipeZip {
public static void main(String[] args) {
if (args.length < 1){
System.out.println("java rookie.demo.PipeZip zipfile");
return;
}
try {
String sFileName = args[0];
File file = new File(sFileName);
File tFile = new File(sFileName + ".00000"); // 临时文件
file.renameTo(tFile);
byte[] buf = new byte[1024];
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(sFileName));
BufferedOutputStream bos = new BufferedOutputStream(zos);
ZipFile zFile = new ZipFile(tFile);
for (Enumeration e = zFile.entries() ; e.hasMoreElements() ;) {
ZipEntry zEntry = (ZipEntry)e.nextElement();
if (zEntry.getName().equals("WEB-INF/web.xml")) {
PrintWriter writer = new PrintWriter(bos);
zEntry = new ZipEntry(zEntry.getName());
zos.putNextEntry(zEntry);
writer.println("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
writer.println("<web-app>");
writer.println("<servlet/>");
writer.println("</web-app>");
writer.flush();
} else {
BufferedInputStream bis = new BufferedInputStream(zFile.getInputStream(zEntry));
zEntry = new ZipEntry(zEntry.getName());
zos.putNextEntry(zEntry);
int count;
while ((count = bis.read(buf, 0, 1024)) > -1) {
bos.write(buf, 0, count);
}
//zos.closeEntry();
bis.close();
}
}
zFile.close();
bos.close();
zos.close();
tFile.delete();
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
import java.io.*;
import java.util.*;
import java.util.zip.*;
public class PipeZip {
public static void main(String[] args) {
if (args.length < 1){
System.out.println("java rookie.demo.PipeZip zipfile");
return;
}
try {
String sFileName = args[0];
File file = new File(sFileName);
File tFile = new File(sFileName + ".00000"); // 临时文件
file.renameTo(tFile);
byte[] buf = new byte[1024];
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(sFileName));
BufferedOutputStream bos = new BufferedOutputStream(zos);
ZipFile zFile = new ZipFile(tFile);
for (Enumeration e = zFile.entries() ; e.hasMoreElements() ;) {
ZipEntry zEntry = (ZipEntry)e.nextElement();
if (zEntry.getName().equals("WEB-INF/web.xml")) {
PrintWriter writer = new PrintWriter(bos);
zEntry = new ZipEntry(zEntry.getName());
zos.putNextEntry(zEntry);
writer.println("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
writer.println("<web-app>");
writer.println("<servlet/>");
writer.println("</web-app>");
writer.flush();
} else {
BufferedInputStream bis = new BufferedInputStream(zFile.getInputStream(zEntry));
zEntry = new ZipEntry(zEntry.getName());
zos.putNextEntry(zEntry);
int count;
while ((count = bis.read(buf, 0, 1024)) > -1) {
bos.write(buf, 0, count);
}
//zos.closeEntry();
bis.close();
}
}
zFile.close();
bos.close();
zos.close();
tFile.delete();
} catch (Exception exp) {
exp.printStackTrace();
}
}
}