Java数据压缩格式程序设计方法之一

本文详细介绍使用Java进行ZIP和GZIP格式数据压缩的方法,包括压缩文件的创建与解压缩过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自:http://tech.ccidnet.com/art/322/20030609/49455_1.html



Java数据压缩格式程序设计方法之一

 

  基于Java语言的健壮性、跨平台应用能力以及面向对象的程序设计特征等因素,Java语言一直是软件工程师在构建网络应用程序,特别是需要在异构平台下运行的软件系统时的首选程序设计语言。

  但是,由于网络带宽的限制,特别是开发以互联网为传输媒介的软件系统时,软件在运行过程中的数据传输效率会成为评价一套软件系统性能的重要指标。由于网络的数据传输速度是软件运行的客观因素,因此,在这种情况下,程序设计人员首先考虑的减少软件系统运行过程中需要传输的数据量,如果有些数据必须要传输,则软件工程师通常将这些数据在发送端进行压缩,而在数据接收端将数据解压缩,从而主动减少应用系统数据传输量。

  JDK环境中提供了多种类型的数据压缩方式,总结起来,利用Java语言可以创建的数据文件压缩格式包括如下类型:

  ●ZIP格式

  ●GZIP格式

  ●JAR格式

  在本系列文章中,将分别对利用Java语言创建类型数据压缩文件的方法,以及JDK API中相关对象的结构和成员方法的应用形式进行说明。

第一部分 ZIP压缩格式程序设计方法

  1 ZIP压缩格式简介

  在JDK API中,定义了多种类型用于创建ZIP格式压缩文件的API。程序设计人员在开发网络应用程序时,可以基于这些API,编写将原始数据压缩成为ZIP格式的压缩数据,便于网络传输。那么,ZIP压缩格式的定义形式是什么呢?

  ZIP压缩格式是在基于互联网进行数据传输过程中,被广泛采用的数据文件压缩格式。由于ZIP格式压缩文件可由多个压缩源文件构成,因此,在单个压缩文件内容的最后,是整个压缩文件的名称和定义目录结构的描述内容。在创建ZIP格式压缩文件过程中,其文件内容构成为:

  [当前文件头+压缩数据+数据描述] . . .

  [目录和文件结构]

  ZIP压缩格式的文件头描述字段和压缩数据描述内容字段的名称和占用字节数如下表所示:

  表1 ZIP格式压缩文件文件头和压缩数据描述内容

  

  ZIP压缩文件中目录和文件结构描述内容如下表所示:

  表2 ZIP格式压缩文件目录结构描述内容

  

  当然,在利用JDK API创建压缩数据文件时,不需要详细了解上述ZIP文件定义格式。但是,JDK中定义的多种类型用于进行数据压缩和管理的对象,正是根据上述格式实现数据压缩和解压缩的。

  2 JDK API中ZIP压缩格式支持对象

  ZIP压缩格式是在Windows操作系统环境中经常应用的压缩格式。ZIP压缩格式的压缩比高、压缩速度快,因而成为利用Java语言定义需要在网络中进行数据传输时,数据压缩格式的首选。

  在JDK API的java.util.zip包中,定义了多种类型用于创建和读取zip压缩格式文件的对象,常用对象的定义形式和主要成员方法如下:

  ●ZipEntry

  由于可以将多个文件压缩到同一压缩文件中,因此,JDK API中定义的ZipEntry对象用于标识ZIP压缩文件中每个原始文件的入口。该对象的定义结构为:

  对象定义结构:

  java.util.zip.ZipEntry

  静态成员变量:

  CENATT、CENATX、CENCRC … …

这些静态成员变量用于定义在压缩过程中采用的压缩算法。

  构造方法:

ZipEntry(String name) 采用字符串类型参数name定义压缩文件中的原始文件入口对象实例。

  ZipEntry(ZipEntry e) 采用ZipEntry对象类型参数e定义压缩文件中的原始文件入口对象实例。

  成员方法:

  long getCompressedSize() 获取压缩文件的大小

  void setCompressedSize(long csize) 设置压缩文件的大小

  int getMethod() 获取压缩时采用的压缩算法

  void setMethod(int method) 设置压缩算法

  long getSize() 获取压缩原始文件的大小

  void setSize(long size) 设置压缩原始文件的大小

  long getTime() 获取压缩文件入口标识的定义时间

  void setTime(long time) 设置压缩文件入口标识的定义时间

  boolean isDirectory() 判断该压缩入口标识是否代表目录

  String getName() 返回压缩入口标识的名称

  ●ZipFile

  该对象用于从ZIP压缩格式文件中读取压缩原始文件的入口。

  对象定义结构:

  java.util.zip.ZipFile

  静态成员变量:

  CENATT、CENATX、CENCRC … …

这些静态成员变量用于定义在压缩过程中采用的压缩算法。

  构造方法:

  ZipFile(File file) 从File对象代表的压缩文件中读取压缩原始文件。

  ZipFile(File file, int mode) 从File对象代表的压缩文件中读取压缩原始文件,并且可以指定ZIP文件读取模式。

  ZipFile(String name) 打开字符串参数name表示的ZIP压缩文件。

  成员方法:

void close() 关闭被读取的ZIP压缩文件

  Enumeration entries() 枚举出ZIP压缩文件中的各个压缩原始文件入口(Entry)

  ZipEntry getEntry(String name) 获取压缩文件中的各个压缩原始文件入口

  InputStream getInputStream(ZipEntry entry) 通过ZIP压缩文件中的入口创建输入流对象

String getName() 获取ZIP压缩文件的名称

  int size() 获取压缩文件中的入口数量

  ●ZipInputStream

  该对象用于从ZIP压缩文件中创建输入流对象。

  对象定义结构:

  java.util.zip.ZipInputStream

  静态成员变量:

  CENATT、CENATX、CENCRC … …

这些静态成员变量用于定义在压缩过程中采用的压缩算法。

  构造方法:

  ZipInputStream(InputStream in) 应用输入流对象创建从ZIP文件中读取数据的输入流对象。

  成员方法:

int available() 判断当前入口指定的压缩原始文件中是否还有未读数据。

  void close() 关闭ZIP输入流对象

  void closeEntry() 关闭被读取的ZIP入口,并移动到下一压缩原始文件入口。

  protectedZipEntry createZipEntry(String name) 利用指定的名称创建ZipEntry对象实例。

  ZipEntry getNextEntry() 将输入流对象移动到下一入口对象。

  int read(byte[] b, int off, int len) 从当前ZipEntry中读取字节数组。

  long skip(long n) 将输入流指定的读取数据位置移动n个字节。

  ●ZipOutputStream

  该数据输出流对象用于创建ZIP压缩文件。

  对象定义结构:

  java.util.zip.ZipOutputStream

  静态成员变量:

  CENATT、CENATX、CENCRC … …

这些静态成员变量用于定义在压缩过程中采用的压缩算法。

  构造方法:

  ZipOutputStream(OutputStream out) 应用输出流对象实例创建ZIP格式输出流对象。

  成员方法:

void close() 关闭ZIP输出流对象。

  void closeEntry() 关闭当前ZIP输出流对象指定的Entry,并移动到下一Entry。

  void putNextEntry(ZipEntry e) 在ZIP压缩文件中创建新的压缩原始文件入口。

  void setComment(String comment) 设置压缩文件的说明信息。

  void setMethod(int method) 设置采用的压缩算法。

  void write(byte[] b, int off, int len) 通过ZIP输出流对象向压缩文件中输出字节数组b。

  3 创建ZIP压缩格式文件实例

经过前面对JDK API中创建ZIP压缩格式文件的相关对象的结构、成员方法定义形式的说明,读者一定会问如何应用这些对象和对象中定义的成员方法呢?请读者看下面的实例代码:

//ZipDemo.java
import java.io.*; 
import java.util.zip.*; 
public class ZipDemo 
{ 
public static void main(String[] args) 
{ 
if (args.length !=2 ) 
{
System.out.println("请输入被压缩文件的名称和压缩文件的名称!"); 
System.exit(1); 
} 
try 
{ 
//创建文件输入流对象 
FileInputStream in = new FileInputStream( args[0] ); 
//创建文件输出流对象
FileOutputStream out = new FileOutputStream( args[1] ); 
//创建ZIP数据输出流对象 
ZipOutputStream zipOut = new ZipOutputStream( out ); 
//创建指向压缩原始文件的入口
ZipEntry entry = new ZipEntry( args[0] );
zipOut.putNextEntry( entry );
//向压缩文件中输出数据
int nNumber; 
byte[] buffer = new byte[512]; 
while ((nNumber=in.read(buffer)) != -1) 
zipOut.write(buffer,0,nNumber); 
//关闭创建的流对象
zipOut.close(); 
out.close(); 
in.close(); 
}
catch(IOException e) 
{ 
System.out.println( e ); 
} 
} 
}

  上面的程序用于将命令行中指定的文件进行压缩,并创建ZIP格式的压缩文件。

  在该程序的实现代码中,首先创建用于进行文件输入和输出的FileInputStream和FileOutputStream对象,并以FileOutputStream对象实例为参数创建ZipOutputStream对象实例,从而为创建ZIP格式压缩文件建立数据流基础。

  在随后的代码中,以被压缩文件的文件名为参数,创建在ZIP压缩文件中指向压缩原始文件的Entry对象实例,并利用putNextEntry方法将该Entry存储进入压缩文件中。最后,利用ZipOutputStream对象中定义的write方法向输出流中写出从压缩原始文件中读取的数据,从而创建ZIP格式的压缩文件。

  在Java中创建ZIP格式压缩文件的方法很简单,并且创建的压缩文件利用WinZip、WinRAR等类型的压缩管理软件均能够打开。那么,如何利用JDK API中定义的对象将被压缩的文件解压缩呢?请读者看下一节的内容。

  4 ZIP格式文件解压缩实例

下面的程序用于将利用JDK API中定义对象的成员方法创建的ZIP格式压缩文件进行解压缩,从而恢复压缩原始文件:

import java.io.*;
import java.util.zip.*; 
 
public class UnzipDemo 
{
public static void main(String[] args) 
{ 
if ( args.length !=2 ) 
{ 
System.out.println("Usage:java ungzip "); 
System.exit(1); 
} 
try 
{ 
//创建文件输入流对象实例 
FileInputStream in = new FileInputStream( args[0] ); 
//创建Zip压缩格式输入流对象实例 
ZipInputStream zipin = new ZipInputStream( in ); 
//创建文件输出流对象实例 
FileOutputStream out = new FileOutputStream( args[1] ); 
//获取Entry对象实例
ZipEntry entry = zipin.getNextEntry();
byte[] buffer = new byte[1024]; 
int nNumber; 
while ((nNumber = zipin.read(buffer, 0, buffer.length)) != -1) 
out.write(buffer, 0, nNumber); 
//关闭文件流对象	
zipin.close(); 
out.close(); 
in.close(); 
}
catch(IOException e) 
{ 
System.out.println(e); 
} 
} 
}

  5小结

  在本部分的内容中,首先介绍了ZIP格式的数据压缩形式。在随后的内容中,对JDK API中ZIP格式的相关支持方法进行详细分析后,以实际代码的形式讲解了创建ZIP压缩格式和ZIP压缩数据文件解压缩的程序设计方法,相信本讲中的程序代码对读者的数据压缩程序有所帮助。

  在下一讲的内容中,将对java.util.zip包中定义支持的另外一种数据压缩格式GZIP的程序设计方法进行讲解。




gzip

1、GZIP压缩格式简介
  
  在JDK API中,同样定义了多种类型用于创建和解除GZIP压缩格式数据文件的通用对象和方法,用于基于JDK编写GZIP压缩数据管理程序。
  
   GZIP压缩格式是在Sun Solaris操作系统中广泛采用的压缩数据格式。由于在数据压缩过程中可以采用多种类型的压缩算法,因此,压缩文件的压缩比很高。另外,在创建的压缩文 件中,定义了用于表述时间和文件属主的时戳(Time Stamp),可以使文件方便地在网络中传输和交换。
  
  GZIP压缩数据文件由一系列的数字构成,而各数字对应如下描述压缩文件信息的字段:
  
  ID1:缺省值31,用于标识GZIP压缩格式;
  
  ID2:缺省值139,用于标识GZIP压缩格式;
  
  CM:采用的压缩方法,其值为0~7是保留值,8标识采用“deflate”压缩方法;
  
  FLG:用于标识各占用位的标志;
  
  MTIME:记录了最近修改时间;
  
  XFL:用于标识采用压缩算法的选项;
  
  OS:定义了操作系统类型;
  
  XLEN:定义了附加信息段的长度;
  
  COMM:压缩文件说明信息;
  
  CRC32:记录了CRC32算法采用的循环冗余校验值。
  
  上述信息完整描述了GZIP压缩格式数据。当然,基于JDK开发的压缩数据管理程序,不需要明确知道上述压缩数据定义格式,只需要创建相应的管理对象并调用这些对象中定义的方法即可。
  
  2、JDK API中ZIP压缩格式支持对象
  
  GZIP压缩格式是在JDK API中定义支持的另外一种数据压缩格式。由上面介绍的GZIP格式数据压缩方法可知:GZIP压缩格式具有更大的压缩比,因此,在Unix操作系统中,这种类型的数据压缩形式的应用十分普及。
  
  与JDK API对ZIP压缩格式的支持不同,在JDK API中,只定义了GZIPInputStream和GZIPOutputStream两种类型的流(Stream)对象,用于在基于流的数据传输过程中实现数据压缩。这两个对象的继承定义结构如下所示:
  
  
  
  java.lang.Object
  
  |
  
  +--java.io.InputStream
  
  |
  
  +--java.io.FilterInputStream
  
  |
  
  +--java.util.zip.InflaterInputStream
  
  |
  
  +--java.util.zip.GZIPInputStream(java.util.zip.GZIPOutputStream)
  
  
  
   以采用GZIP格式进行数据输入处理GZIPInputStream对象为例,由上述对象的继承定义结构可以看出:该对象继承了 InflaterInputStream流对象。需要说明的是:在ZIP压缩包中,定义了Inflater和Deflater两个对象,用于基于ZLIB 压缩库实现多种格式的数据压缩和解压缩。因此,InflaterInputStream流对象的作用是采用ZLIB库作为数据压缩管理的引擎,而 GZIPInputStream对象则进一步将流的数据加工进行细化,用于读取GZIP格式的压缩数据,同理,GZIPOutputStream对象用于 创建GZIP格式的压缩数据文件。下面,将对两个对象的定义内容进行说明:
  
  ●GZIPInputStream
  
  对象定义结构:
  
  java.util.zip.GZIPInputStream
  
  静态成员变量:
  
  protected CRC32 crc:用于说明采用的数据压缩算法为CRC-32;
  
  protected boolean eos:说明输入流对象结束读取输入数据;
  
  构造方法:
  
  GZIPInputStream(InputStream in):采用默认的缓冲区字节数创建输入流对象;
  
  GZIPInputStream(InputStream in, int size):创建由整数类型变量size指定缓冲区字节数的输入流对象;
  
  成员方法:
  
  该对象只定义了如下两个成员方法:
  
  void close():关闭输入流对象;
  
  int read(byte[] buf, int off, int len):读取输入流的数据到buf字节数组中。
  
  ●GZIPOutputStream
  
  对象定义结构:
  
  java.util.zip.GZIPOutputStream
  
  静态成员变量:
  
  protected CRC32 crc:用于说明采用的数据压缩算法为CRC-32;
  
  构造方法:
  
  GZIPOutputStream(OutputStream out):采用默认的缓冲区字节数创建输出流对象;
  
  GZIPOutputStream(OutputStream out, int size):创建由整数类型变量size指定缓冲区字节数的输出流对象;
  
  成员方法:
  
  void close():关闭输出流对象;
  
  void finish():结束数据输出,但不关闭输出流对象;
  
  void write(byte[] buf, int off, int len):将字节数组buf中的内容压缩输出到输出流对象中。
  
  3、 创建GZIP压缩格式文件实例
  
  经过前面对JDK API中创建GZIP压缩格式文件的相关对象的结构、成员方法定义形式的说明,读者一定会问如何应用这些对象和对象中定义的成员方法呢?请读者看下面的实例代码:
  
  
  
  //ZipDemo.java
  
  import java.io.*; 
  
  import java.util.zip.*; 
  
  public class GZIPDemo 
  
  { 
  
  public static void main(String[] args) 
  
  { 
  
  if (args.length !=2) 
  
  { 
  
  System.out.println("Usage:java GZIPDemo SourceFile DestnFile" + args.length); 
  
  System.exit(1); 
  
  } 
  
  try 
  
  { 
  
  int number; 
  
  //打开需压缩文件作为文件输入流 
  
  FileInputStream fin = new FileInputStream(args[0]); 
  
  //建立压缩文件输出流
  
  FileOutputStream fout=new FileOutputStream(args[1]); 
  
  //建立GZIP压缩输出流 
  
  GZIPOutputStream gzout=new GZIPOutputStream(fout); 
  
  //设定读入缓冲区尺寸
  
  byte[] buf=new byte[1024]; 
  
  while ((number = fin.read(buf)) != -1) 
  
  gzout.write(buf,0,number); 
  
  gzout.close(); 
  
  fout.close(); 
  
  fin.close(); 
  
  }
  
  catch(IOException e) 
  
  { 
  
  System.out.println(e); 
  
  } 
  
  } 
  
  }
  
  
  
  上面的程序用于将命令行中指定的文件SourceFile进行压缩,创建GZIP格式的压缩文件DestnFile。
  
   在该程序的实现代码中,首先创建用于进行文件输入和输出的FileInputStream和FileOutputStream对象,并以 FileOutputStream对象实例为参数创建GZIPOutputStream对象实例,从而为创建GZIP格式压缩文件建立数据流基础。
  
  在随后的代码中,利用FileInputStream对象中定义的read方法,从源文件中读取待压缩文件的内容,同时利用GZIPOutputStream对象中定义的write方法将压缩后的数据写出到输出文件中,从而实现数据文件的GZIP格式压缩处理。
  
  在Java中创建GZIP格式压缩文件的方法很简单,并且利用WinZip、WinRAR等类型的压缩管理软件均能够打开创建的GZIP格式的压缩文件。那么,如何利用JDK API中定义的对象将被压缩的文件解压缩呢?请读者看下一节的内容。
  
  4、GZIP格式文件解压缩实例
  
  下面的程序用于将利用JDK API中定义对象的成员方法,将GZIP格式压缩文件进行解压缩,从而恢复压缩原始文件:
  
  
  
  //UnGZIPDemo.java
  
  import java.io.*; 
  
  import java.util.zip.*; 
  
  public class UnGZIPDemo 
  
  { 
  
  public static void main(String[] args) 
  
  { 
  
  if (args.length !=2) 
  
  { 
  
  System.out.println("Usage:java UnGZIPDemo GZIPFile DestnFile"); 
  
  System.exit(1); 
  
  } 
  
  try 
  
  { 
  
  int number;
  
  //建立GZIP压缩文件输入流 
  
  FileInputStream fin=new FileInputStream(args[0]); 
  
  //建立GZIP解压工作流 
  
  GZIPInputStream gzin=new GZIPInputStream(fin); 
  
  //建立解压文件输出流 
  
  FileOutputStream fout=new FileOutputStream(args[1]); 
  
  //设定读入缓冲区尺寸
  
  byte[] buf=new byte[1024]; 
  
  while ((nnumber=gzin.read(buf,0,buf.length)) != -1) 
  
  fout.write(buf,0,nnumber); 
  
  gzin.close(); 
  
  fout.close(); 
  
  fin.close(); 
  
  }
  
  catch(IOException e) 
  
  { 
  
  System.out.println(e); 
  
  } 
  
  } 
  
  }
  
  
  
   在GZIP格式压缩文件解压缩程序代码中,仍然首先创建FileInputStream和FileOutputStream对象,并基于创建的 FileInputStream对象创建GZIPInputStream对象。在随后的代码中,调用GZIPInputStream对象中定义的read 方法,在从压缩文件中读取数据内容并进行解压缩处理后,将解除压缩后的数据内容利用文件输出流对象进行输出,从而实现数据文件的解压缩处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值