位于上海,服务全国!

位于上海,服务全国!

使用Java归档文件

作者:admin 分类: 时间:2016-05-12 10:15:53 点击量:2781


存档放在一个作为一个单元的一个或多个文件的集合。通常,在Java程序中,我们会遇到称为JAR(Java归档)的归档文件。这种类型的文件对于每一个Java程序员都不陌生。归档文件通常通过使用文件归档软件如WinZip,7-zip,tar等创建。这些类型的文件特别可用于多个文件存储和作为单个单元的传输。文件归档有时会采用数据压缩和加密的方式。本文通过使用Java编程深入研究了一些与归档文件工作相关的关键概念。


数据压缩的概述
档案文件可以采用不同的数据编码技术来减少一个文件的内容所占字节数。 有多种压缩算法来减小文件大小;通常它们有两种类型: 无损和有损压缩。 无损压缩算法的工作不会产生任何数据损失,当数据文件的大小被减少时。 另一方面,有损压缩是假定丢失一些信息是可接受的。 例如,当压缩一个图像文件时,一些颜色的损失不会造成太大的视觉差异,但可显著降低文件大小。 这对于诸如图像,视频,等等类型的文件是可接受的。 但是,这样的有损压缩并不对于包含产品信息的文件是可接受的。此时,我们需要应用无损数据压缩技术,因为当被解压缩时,我们需要的是不丢失任何数据的精确信息。


例如,对于一个无损数据压缩,一个字符串,如‘AAAAAABBBB’可被存储为'6A4B';换言之,“六A和4 B的'。 保存“6A4B”的空间比存储字符重复序列的空间少得多。 这个简单的技术被称为运行长度算法(RLE)。 RLE可通过被称为统计冗余的方法,其通过计数器代替重复序列的字符进而减小文件大小。 当前有损和无损数据压缩的算法有很多种。 例如, Lempel-Ziv (LZ)算法的变量 - LZR(Lempel-Ziv-Renau)算法,其形成了一个基础的ZIP文件,LZW(Lempel-Ziv-Welch)在GIF图像内使用。


编码技术,如MP3,Vorbis和AAC都是有损的,而JPEG 2000, FLIF,等等都是无损的。 它们对于图像或音频/视频压缩是非常有用的,其丢失几个比特位并不会影响整个内容,但肯定会降低一些品质,如果你比较挑剔微小的细节。试着听一个MP3音频和相同的文件,以未压缩音频格式,如WAV,AIFF,AU,或PCM格式。

https://en.wikipedia.org/wiki/Data_compression
https://en.wikipedia.org/wiki/Lossless_compression
https://en.wikipedia.org/wiki/Audio_file_format
这个过程被反转以获得实际的数据内容时,被称为解压缩。

java归档运行图
 
图形1. 归档如何运行

在Java中压缩数据
Java提供了两个API类,被称为Deflater和Inflater,在java.util.zip包内进行压缩和解压数据。这两个类提供了Java的核心压缩及解压缩工具。执行这些类的方式如下。




创建一个Deflater实例
输入字符串的字节格式
调用finish()方法至输入数据的信号终端
调用deflate()方法进行压缩
调用end()方法来结束压缩过程
同样,数据恢复/解压缩,请按照下列步骤操作:


创建一个Inflater实例
压缩字节作为输入数据
调用inflate()方法进行解压
调用end()方法来结束解压过程
让我们尝试一个简单的字符串。不要混淆:Deflater是压缩和Inflater是解压。

package org.mano.example;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class ArchiveDemo {

   public static void main(String[] args)
         throws IOException, DataFormatException {


      String inputData = "Lorem ipsum dolor sit amet,
         consectetur adipiscing elit, "
      + "sed do eiusmod tempor incididunt ut labore et
         dolore magna aliqua. "
      + "Ut enim ad minim veniam, quis nostrud exercitation
         ullamco laboris "
      + "nisi ut aliquip ex ea commodo consequat. Duis aute
         irure dolor in "
      + "reprehenderit in voluptate velit esse cillum dolore
         eu fugiat nulla "
      + "pariatur. Excepteur sint occaecat cupidatat non
         proidendecompressort,"
      + "sunt in culpa qui officia deserunt mollit anim id
         est laborum.";


      byte[] compressedByte = compress(inputData.getBytes(),
         Deflater.BEST_COMPRESSION, false);
      byte[] decompressedByte=decompress(compressedByte, false);


      String outputData=new String(decompressedByte);


      System.out.println("Input Data: " + inputData);
      System.out.println("Uncompressed data length: "
         + inputData.getBytes().length);
      System.out.println("Compressed data length: "
         + compressedByte.length);
      System.out.println("Decompressed data length: "
         + decompressedByte.length);
      System.out.println("Output Data: " + outputData);


   }


   public static byte[] decompress(byte[] input, boolean format)
         throws IOException, DataFormatException {
      Inflater inflater = new Inflater(format);
      inflater.setInput(input);
      ByteArrayOutputStream baout = new ByteArrayOutputStream();
      byte[] buff = new byte[1024];
      int count = 0;


      while (!inflater.finished()) {
         count = inflater.inflate(buff);
         if ( count > 0)
            baout.write(buff, 0, count);
      }
      inflater.end();
      return baout.toByteArray();
   }


   public static byte[] compress(byte[] data, int compressionLevel,
         boolean format) throws IOException {


      Deflater deflater = new Deflater(compressionLevel, format);
      deflater.setInput(data);
      deflater.finish();


      ByteArrayOutputStream baout = new ByteArrayOutputStream();
      byte[] buff = new byte[1024];
      int count = 0;


      while (!deflater.finished()) {
         count = deflater.deflate(buff);
         if (count > 0)
            baout.write(buff, 0, count);
      }
      deflater.end();
      return baout.toByteArray();
   }
}
以ZIP格式运行
假设我们有许多文件被存档于ZIP格式;我们可以使用java.util.zip包中的类,如ZipEntry,ZipInputStream,ZipOutputStream,以及ZipFile以ZIP文件格式运行。

package org.mano.example;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class ArchiveDemo2 {


   private static ZipOutputStream zout;


   public static void main(String[] args)
      throws IOException, FileNotFoundException {


         String zipFile = "myzipfile.zip";
         String[] files = { "myfile.txt, /home/mano/doc/file2.txt,
             file3.png" };
         zip(zipFile, files);
      }


      public static void zip(String zipFile, String[] files)
            throws IOException, FileNotFoundException {
         String currentDirectory = System.getProperty("user.dir");


      zout = new ZipOutputStream(new
         BufferedOutputStream(new FileOutputStream(zipFile)));
      zout.setLevel(Deflater.BEST_COMPRESSION);
      for (int i = 0; i < files.length; i++) {
      File file = new File(files[i]);
      if (!file.exists()) {
         System.out.println("File " + file.getAbsolutePath()
            + " not found ");
         System.out.println("Aborted.");
            return;
      }
      ZipEntry ze = new ZipEntry(files[i]);
      zout.putNextEntry(ze);


      BufferedInputStream buffin = new BufferedInputStream(new
         FileInputStream(files[i]));


      byte[] buffer = new byte[1024];
      int count = -1;
      while ((count = buffin.read(buffer)) != -1) {
         zout.write(buffer, 0, count);
      }
         buffin.close();
      }


      zout.closeEntry();
      zout.close();
      System.out.println("Output written to "
         + currentDirectory + File.separator + zipFile);
   }
}
读取ZIP格式文件的内容


package org.mano.example;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


public class ArchiveDemo3 {


   public static void main(String[] args) {
      String zipFile = "myzipfile.zip";
      String unziploc = "/home/mano/test";
      unzip(zipFile, unziploc);
   }


   public static void unzip(String zipFile, String unziploc) {
      try (ZipInputStream zin = new ZipInputStream(new
         BufferedInputStream(new FileInputStream(zipFile)))) {


      ZipEntry ze = null;
      while ((ze = zin.getNextEntry()) != null) {


      File file = new File(unziploc + File.separator
         + ze.getName());
      File root = file.getParentFile();
      if (!root.exists()) root.mkdirs();
      file.createNewFile();
      BufferedOutputStream buffout = new BufferedOutputStream(
      new FileOutputStream(unziploc + File.separator
         + ze.getName()));
      byte[] buffer = new byte[1024];
      int count = -1;
      while ((count = zin.read(buffer)) != -1) {
         buffout.write(buffer, 0, count);
      }
         buffout.close();
      }


      System.out.println("Contents extracted to " + (new
         File(unziploc)).getAbsolutePath());
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}
结论

Java API已有一些类来处理一些常见的其他归档文件格式,如GZIP文件和JAR文件。归档文件基本上包含目录结构的元数据信息,错误检测和恢复信息等等。java.util.zip包提供了一些优秀的实用工具类以在存档支持之外处理校验。


来源: Developer.com