近来,我被安排从事一项很重要的工作:把Web日志放入SQL数据库中进行分析,不巧的是,这些日志文件是GZIP格式,每一次请求信息都被加密,需要解析。我一直认为JAVA是做好的程序语言,所以我决定编一个程序来解析这些日志文件。
我一直担心解析加密文件的解压缩过程,所以我决定察看一下J2SDK 1.3.1 API文档,看看是否有帮助,在JAVA.util压缩包的右侧列表中正好有JAVA.util.jar和JAVA.util.ZIP package,本文中我主要谈谈解读压缩文件并轻松演示一下。
JAVA.util.ZIP压缩包对读写ZIP和GZIP格式文件提供了分类,从这些格式中读取文件就需要创建合适的 InflaterInputStream,先以GZIP格式为例。
GZIPInputStream可以以InputStream (象FileInputStream)为例,在我的例子中,我想要读取一个文件中的一行这样我就要用StringTokenizer解析每一个entry,为了达到这一目的,我采用在代码下创建BufferedReader的方法。(见表A中的所有源代码)
gZIPReader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(fileName))));
这行代码可以让我们同时在一行中读取整个文件,看一下下面的结果:
C:>JAVA ZIP test.txt.gz
contents of test.txt.gz...
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
line of this test file that is compressed.
这是GZIP格式的文件,ZIP文件是一个小陷阱,因为你可以包含一个或更多的文件,ZIPFile类可以简化一个文件的重复情况,ZIPFile object可以由File object或说明文件名和路径的String来创建。ZIPFile可以提供大量的ZIPEntry objects,从中,可以得到文件的一些值(比如文件大小、压缩比例等等)。ZIPFile和ZIPEntry结合使用, 可以得到GZIPInputStream来读取整个目录内容见表B。
也可以采用同样的方式读取上面提到的GZIP文件。
JAVA.util.jar压缩包对读写JAR (JAVA 文档)格式文件提供了分类,这是基于ZIP文件的标准格式,压缩包中的大多数类都扩展了JAVA.util.ZIP压缩包的副本。从JAR文件中读信息与从ZIP中读信息非常相似,JarFile类与ZIPFile类功能相同。(实际上是演变过来的)
JarFile详细的清单,见表A,创建了JarFile的同时也就生成了详细的清单目录,之后,每一个entry都按与前面例子中ZIP文件相同的方式来读取信息(毕竟他们都是ZIP文件),你可能会注意到代码中包含检查entry是否是一个目录的语句,这一方法在ZIPEntry类中也有,在创建并读取InflaterInputStream之前核实一些entry是否是目录路径。
解析加密需要一定的过程,从InflatorInputStream中读取信息可以节省时间和磁盘空间。我要处理的文件是非常大的(30 MB压缩, 150 MB未压缩)。直接读取压缩文件,那么在读之前就没有时间来解压缩,同时磁盘也没有足够的空间了。首先,如果文档非常小,应用API是很困难的,但是搜索一下JAVA论坛,就会有拨云见日的感觉。下一个逻辑步骤就是往压缩文件中写数据,在下一篇文章中,我会很高兴地为大家说明这一问题。