文件中数据冗余的最简单的类型是"字符的复制"。让我们先来看下面一个字符串:
JJJJJJAAAAVVVVAAAAAA
这个字符串可以用更简洁的方式来编码,那就是通过替换每一个重复的字符串为单个的实例字符加上记录重复次数的数字来表示,上面的字符串可以被编码为下面的形式:6J4A4V6A
在这里,"6J"意味着6个字符J,"4A"意味着4个字符A,以此类推。这种字符串压缩方式称为"行程长度编码"方式,简称RLE。
再举一个例子,考虑一下矩形图像的存储。一个单色位图,可以被存储为下面这种形式。
另外一种方式是将图像存为一个图元文件:
Rectangle 11, 3, 20, 5
上面的表示方法是讲矩形的起始坐标是(11,3),宽度是20,高度是5。
上述的矩形图像可以使用RLE编码方式压缩,通过对相同位记数表示如下:
0, 40
0, 40
0,10 1,20 0,10
0,10 1,1 0,18 1,1 0,10
0,10 1,1 0,18 1,1 0,10
0,10 1,1 0,18 1,1 0,10
0,10 1,20 0,10
0,40
上面第一行是讲图像的第一行由40个0组成。第三行是讲图像的第三行是由10个0加上20个1再加上10个0组成,其它行以此类推。
大家注意,RLE方法需要将其表示的文件与编码文件分开。所以,这种方法不能应用于所有的文件。其它的压缩技术包括变长编码(也被称为哈夫曼编码),还有其它的方法。要想了解更详细的信息,请参考有关数据和图像压缩技术方面的图书,一定会有收获的。
数据压缩有很多益处。不管怎么说,最主要的好处就是减少存储方面的需求。同样的,对于数据通信来讲,压缩数据在媒体中的将导致信息传输数据的提升。数据的压缩能够通过软件在现有的硬件设备上实现或者通过带有压缩技术的特殊的硬件设备来实现。
ZIP VS GZIP
如果你是在Windows系统下工作,你可能会对工具WinZip很熟悉,是用来创建压缩档案和解开压缩档案的。而在UNIX平台上,会有一些不同,命令tar用来创建一个档案文件(并不压缩),其它的程序(gzip或compress)用来创建一个压缩档案。
WinZip和PkZip之类的工具同时扮演着归档和压缩两个角色。他们将文件压缩并将其归档。另一方面,gzip并不将文件归档。所以,在UNIX平台上,命令tar通常用来创建一个档案文件,然后命令gzip来将档案文件压缩。
Javautilzip包
Java提供了javautilzip包用来兼容ZIP格式的数据压缩。它提供了一系列的类用来读取,创建,修改ZIP和GZIP格式的文件。它还提供了工具类来计算任意输入流的数目,这可以用来验证输入数据的有效性。该包提供了一个接口,十四个类,和两个异常处理类,如表1所示。
表1: javautilzip包
条目 类型 描述
Checksum 接口 被类Adler32和CRC32实现的接口
Adler32 类 使用Alder32算法来计算Checksum数目
CheckedInputStream 类 一个输入流,保存着被读取数据的Checksum
CheckedOutputStream 类 一个输出流,保存着被读取数据的Checksum
CRC32 类 使用CRC32算法来计算Checksum数目
Deflater 类 使用ZLIB压缩类,支持通常的压缩方式
DeflaterOutputStream 类 一个输出过滤流,用来压缩Deflater格式数据
GZIPInputStream 类 一个输入过滤流,读取GZIP格式压缩数据
GZIPOutputStream 类 一个输出过滤流,读取GZIP格式压缩数据
Inflater 类 使用ZLIB压缩类,支持通常的解压方式
InlfaterInputStream 类 一个输入过滤流,用来解压Inlfater格式的压缩数据
ZipEntry 类 存储ZIP条目
ZipFile 类 从ZIP文件中读取ZIP条目
ZipInputStream 类 一个输入过滤流,用来读取ZIP格式文件中的文件
ZipOutputStream 类 一个输出过滤流,用来向ZIP格式文件口写入文件
DataFormatException 异常类 抛出一个数据格式错误
ZipException 异常类 抛出一个ZIP文件
注意:ZLIB压缩类最初是作为可移植的网络图像文件格式(PNG)标准的一部分开发的,是不受专利保护的。
从ZIP文件中解压缩和提取数据
javautilzip包提供了数据压缩与解压缩所需要的类。ZIP文件的解压缩实质上就是从输入流中读取数据。Javautilzip包提供了类ZipInputStream来读取ZIP文件。ZipInputStream流的创建与其它输入流的创建没什么两样。举个例子,下面的代码段创建了一个输入流来读取ZIP格式的文件:
FileInputStream fis = new FileInputStream("figszip");
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis));
ZIP输入流打开后,你可以使用getNextEntry方法来读取ZIP文件中的条目数,该方法返回一个ZipEntry对象。如果到达文件的尾部,getNextEntry返回null:
ZipEntry entry;
while((entry = zingetNextEntry()) != null) {
// extract data
// open output streams
}
现在,你应该建立一个输出流,如下所示:
int BUFFER = 2048;
FileOutputStream fos = new FileOutputStream(entrygetName());
BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
注意:在这段代码中我们用BufferedOutputStream代替了ZIPOutputStream。ZIPOutputStream和GZIPOutputStream使用内置的512字节缓冲。当缓冲区的大小大于512字节时,使用BufferedOutputStream才是正确的(例子中设置为2048)。ZIPOutputStream不允许你设置缓冲区的大小,GZIPOutputStream也是一样,但创建 GZIPOutputStream 对象时可以通过构造函数的参数指定内置的缓冲尺寸。
这段代码中,使用ZIP内含的条目名称创建一个文件输出流。可以使用entrygetName来得到它的返回句柄。接着读出被压缩的源数据,然后写入输出流:
while ((count = zinread(data, 0, BUFFER)) != -1) {
//Systemoutwrite(x);
destwrite(data, 0, count);
}
最后,不要忘记关闭输入和输出流:
destflush();
destclose();
zinclose();
例程1的源程序UnZipjava显示如何解压缩并从ZIP档案中将文件释放出来。测试这个例子,编译这个类,并运行它,传给它一个ZIP格式的文件作为参数:
prompt> java UnZip somefilezip
注意:somefilezip应该是一个ZIP压缩档案,可以用任何一种ZIP压缩工具来创建,例如WinZip。
Java代码
public static void message(){
// String package_header_signature = "hello";
// int file_num=8;
//
// for(int i=0;i<8;i++){
// int file_path_length="";
int file_size ="";
// String file_path="";
// }
// 只列了简单几个,原因都懂的!
// }
public static void test(String src,String target) throws Exception{
File file =new File(src);
//String target = "g://testpkg";
File targetFile = new File(target);
if(!targetFileexists()){
targetFilecreateNewFile();
}
OutputStream os = new FileOutputStream(targetFile);
//write some message
String package_header_signature = "hello";
addByte(package_header_signaturegetBytes(), os, 4);
//文件个数
int filesum=0;
//文件路径
List<String> strList = new ArrayList<String>();
filesum =listFlieSum(file,strList);
//加入文件个数
addByte(intToByte(filesum,1),os, 1);
for(int i=0;i<strListsize();i++){
File fileInfo = new File(strListget(i));
String file_path = fileInfogetAbsolutePath();
int file_path_length = file_pathlength();
int file_size = getFileSize(fileInfo);
//加入文件路径长度
addByte(intToByte(file_path_length,1), os, 1);//文件路径的长度
//加入文件大小
addByte(intToByte(file_size,4), os, 4);//文件大小
//加入文件路径
addByte(file_pathgetBytes(), os, file_pathlength());//文件路径
}
listFile(file,os);
String crc32 = getFileCRCCode(targetFile);
byte[] crcbyte = crc32getBytes();
osclose();
/
int to byte[] 支持 1或者 4 个字节
@param i
@param len
@return
/
public static byte[] intToByte(int i,int len) {
byte[] abyte=null;
if(len==1){
abyte = new byte[len];
abyte[0] = (byte) (0xff & i);
}else{
abyte = new byte[len];
abyte[0] = (byte) (0xff & i);
abyte[1] = (byte) ((0xff00 & i) >> 8);
abyte[2] = (byte) ((0xff0000 & i) >> 16);
abyte[3] = (byte) ((0xff000000 & i) >> 24);
}
return abyte;
}
public static int bytesToInt(byte[] bytes) {
int addr=0;
if(byteslength==1){
addr = bytes[0] & 0xFF;
}else{
addr = bytes[0] & 0xFF;
addr |= ((bytes[1] << 8) & 0xFF00);
addr |= ((bytes[2] << 16) & 0xFF0000);
addr |= ((bytes[3] << 24) & 0xFF000000);
}
return addr;
}
都是套管子的,按它们包装的顺序反过来 close,这种设计是 Filtered,就是一层套一套,比如 ZipOutputStream 它只负责 zip 压缩,至于内容最终存放在哪里面是由它的构造函数参数 cos 来负责的,而 Cos 只负责按 CRC 32 检验数据,至于数据本身最终又存放在哪里面是由 fileOutputStream 说得算,因此最终数据需要从管道中输出到 fileOutputStream 中的。其它的 OutputStream 都只是进行一次额外的包装处理(装饰)。
一般来说最外面一层的 OutputStream 在 Close 时会同时让它当初接收的构造函数参数也一起 close,也就是说 out 在 close 时会调用 cosclose(); 而 cos 在 close 时会调用 fileOutputStreamclose(); 通常如此,当然可能也有少数例外。
以上就是关于怎么用JAVA解压winrar加密的zip包(不要调用winrar的命令)全部的内容,包括:怎么用JAVA解压winrar加密的zip包(不要调用winrar的命令)、java自定义数据结构碰到了问题,望高手指点、java 关于CheckedOutputStream 流的 *** 作等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)