Java压缩技术的学习
由于工作的需要,经常要手动去打上线安装包,为了方便,自己写程序去帮助打包。使用过Unix或者Linux的人都基本上都用过tar打包以及gzip压缩,但在Windows下使用得最多的压缩还是RAR和Zip压缩吧
一、 tar打包、解包
在java的JDK中没有原生的tar归档类,需要下载开源的包: commons-compress-1.0.jar,所以
第一步是下载jar包,可以到www.findjar.com搜索并下载。
第二步导入到工程中;忽略
第三步编写源代码,在写代码之前使用介绍一下
//打包归档输出流
org.apache.commons.compress.archivers.tar.TarArchiveOutputStream
//解包归档输入流
org.apache.commons.compress.archivers.tar.TarArchiveInputStream
//增加打包归档的条目
void org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.putArchiveEntry(ArchiveEntry arg0)
//设置归档的模式:
TarArchiveOutputStream.LONGFILE_GNU和TarArchiveOutputStream.LONGFILE_ERROR和TarArchiveOutputStream.LONGFILE_TRUNCATE
void org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.setLongFileMode(int longFileMode)
//获取归档文件中的条目
TarArchiveEntry org.apache.commons.compress.archivers.tar.TarArchiveInputStream.getNextTarEntry() throws IOException
下面是打包的源代码:
/**
* tar 打包
* @param source 源文件
* @param dest 目标文件
*/
public static void tar(File source){
logger.info("开始对源文件["+source.getName()+"]打成tar包");
FileOutputStream out = null;
TarArchiveOutputStream tarOut = null; String parentPath = source.getParent();
File dest = new File(parentPath + source.getName() + ".tar");
try{
out = new FileOutputStream(dest);
tarOut = new TarArchiveOutputStream(out);
//解决文件名过长
tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
tarPack(source, tarOut,"");
tarOut.flush();
tarOut.close();
logger.info("成功把源文件打为tar包,名称为:["+dest.getName()+"]");
}catch (Exception e) {
logger.error(e.getMessage(),e);
}finally{
try{
if(out != null){
out.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(tarOut != null){
tarOut.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
}
/**
* 归档
* @param source 源文件或者目录
* @param tarOut 归档流
* @param parentPath 归档后的目录或者文件路径
*/
public static void tarPack(File source,TarArchiveOutputStream tarOut,String parentPath){
if(source.isDirectory()){
tarDir(source,tarOut,parentPath);
}else if(source.isFile()){
tarFile(source,tarOut,parentPath);
}
}
/**
* 归档文件(非目录)
* @param source 源文件
* @param tarOut 归档流
* @param parentPath 归档后的路径
*/
public static void tarFile(File source,TarArchiveOutputStream tarOut,String parentPath){
TarArchiveEntry entry = new TarArchiveEntry(parentPath + source.getName());
BufferedInputStream bis = null;
FileInputStream fis = null;
try {
entry.setSize(source.length());
tarOut.putArchiveEntry(entry);
fis = new FileInputStream(source);
bis = new BufferedInputStream(fis);
int count = -1;
byte []buffer = new byte[1024];
while((count = bis.read(buffer, 0, 1024)) != -1){
tarOut.write(buffer, 0, count);
}
bis.close();
tarOut.closeArchiveEntry();
} catch (IOException e) {
logger.error(e.getMessage(),e);
}finally{
try {
if(bis != null){
bis.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
try {
if(fis != null){
fis.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
/**
* 归档目录
* @param sourceDir 原目录
* @param tarOut 归档流
* @param parentPath 归档后的父目录
*/
public static void tarDir(File sourceDir,TarArchiveOutputStream tarOut,String parentPath){
//归档空目录
if(sourceDir.listFiles().length < 1){
TarArchiveEntry entry = new TarArchiveEntry(parentPath + sourceDir.getName() + "\\");
try {
tarOut.putArchiveEntry(entry);
tarOut.closeArchiveEntry();
} catch (IOException e) {
logger.error(e.getMessage(),e);
}
}
//递归 归档
for (File file : sourceDir.listFiles()) {
tarPack(file, tarOut,parentPath + sourceDir.getName() + "\\");
}
}
以下解包的源代码
/**
* 解归档
* @param source 源归档tar文件
*/
public static void untar(File source){
TarArchiveInputStream tarIn = null;
FileInputStream fis = null;
String parentPath = source.getParent(); BufferedOutputStream bos = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream(source);
tarIn = new TarArchiveInputStream(fis);
TarArchiveEntry entry = null;
while((entry = tarIn.getNextTarEntry()) != null){
File file = new File(parentPath + "\\" + entry.getName());
//为解决空目录
if(entry.isDirectory()){
file.mkdirs();
continue;
}
File parentDir = file.getParentFile();
if(!parentDir.exists()){
parentDir.mkdirs();
} fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
int count = -1;
byte []buffer = new byte[1024];
while((count = tarIn.read(buffer, 0, buffer.length)) != -1){
bos.write(buffer, 0, count);
}
bos.flush();
bos.close();
fos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}finally{
try{
if(fis != null){
fis.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(fos != null){
fos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(bos != null){
bos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(tarIn != null){
tarIn.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
}
二、 gzip压缩、解压
注意gzip不支持压缩目录的;Jdk里提供了类支持压缩文件;默认生成.gz文件
主要对应的Java类为:
//Gzip输入流
java.util.zip.GZIPInputStream
//Gzip输出流
java.util.zip.GZIPOutputStream
压缩源代码
/**
* gzip 压缩,跟源文件在相同目录中生成.gz文件
* @param source 源文件
*/
public static void gzip(File source){
logger.info("开始对源文件["+source.getName()+"]压缩成.gz包");
String dir = source.getParent();
File target = new File(dir + "\\" +source.getName() + ".gz");
FileInputStream fis = null;
FileOutputStream fos = null;
GZIPOutputStream gzipOS = null;
try{
fis = new FileInputStream(source);
fos = new FileOutputStream(target);
gzipOS = new GZIPOutputStream(fos);
int count = -1;
byte [] buffer = new byte[1024];
while((count = fis.read(buffer, 0, buffer.length)) != -1){
gzipOS.write(buffer, 0, count);
}
gzipOS.flush();
gzipOS.close();
logger.info("成功把源文件["+source.getName()+"]压缩为.gz包["+target.getName()+"]");
}catch (Exception e) {
logger.error(e.getMessage(),e);
}finally{
try{
if(fis!=null){
fis.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(fos!=null){
fos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(gzipOS!=null){
gzipOS.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
}
解压.gz包源代码
/**
* 解压.gz包
* @param source 源.gz包
*/
public static void ungzip(File source){
GZIPInputStream gzipIS = null;
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null; String fileName = source.getName();
fileName = fileName.substring(0, fileName.lastIndexOf("."));
try{
fis = new FileInputStream(source);
gzipIS = new GZIPInputStream(fis);
File target = new File(source.getParent() + "\\" + fileName);
fos = new FileOutputStream(target);
bos = new BufferedOutputStream(fos); int count = -1;
byte []buffer = new byte[1024];
while((count = gzipIS.read(buffer, 0, buffer.length)) != -1){
bos.write(buffer, 0, count);
}
bos.flush();
}catch (Exception e) {
logger.error(e.getMessage(),e);
}finally{
try{
if(fis!=null){
fis.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(fos!=null){
fos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(bos != null){
bos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(gzipIS!=null){
gzipIS.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
}
三、 zip压缩、解压
Jdk提供代码技术支持,tar打包跟zip压缩类似的。
在Jdk中主要的类为:
java.util.zip.ZipOutputStream
java.util.zip.ZipInputStream
压缩源代码
/**
* 使用zip压缩文件
* @param source 源文件或者文件夹
*/
public static void zip(File source){
String dir = source.getParent();
File target = new File(dir + "\\" +source.getName() + ".zip");
FileOutputStream fos = null;
ZipOutputStream zipos = null; try{
fos = new FileOutputStream(target);
zipos = new ZipOutputStream(fos);
zipFile(source, zipos, "");
//必须要下面一步,否则会报no such file or directory错误
zipos.close();
}catch (Exception e) {
logger.error(e.getMessage(),e);
}finally{
try {
if(fos != null){
fos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
try {
if(zipos != null){
zipos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
/**
* 递归压缩文件或者文件夹
* @param source 源文件
* @param zipos zip输出流
* @param parentPath 路径
*/
public static void zipFile(File source,ZipOutputStream zipos,String parentPath){
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
//增加目录
if(source.isDirectory()){
File[]files = source.listFiles();
if(files.length < 1){
ZipEntry entry = new ZipEntry(parentPath + source.getName() + "/");
zipos.putNextEntry(entry);
}
for (File file : files) {
zipFile(file, zipos, parentPath + source.getName() + "/");
}
}else if(source.isFile()){
fis = new FileInputStream(source);
bis = new BufferedInputStream(fis);
ZipEntry entry = new ZipEntry(parentPath + source.getName());
zipos.putNextEntry(entry);
int count = -1;
byte []buffer = new byte[1024];
while((count = bis.read(buffer, 0, buffer.length)) != -1){
zipos.write(buffer, 0, count);
}
fis.close();
bis.close();
}
} catch (IOException e) {
logger.error(e.getMessage(),e);
}finally{
try {
if(bis != null){
bis.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
try {
if(fis != null){
fis.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
解压源代码
/**
* 解压zip文件
* @param source 源.zip文件
*/
public static void unzip(File source){
ZipInputStream zipIn = null;
FileInputStream fis = null;
String parentPath = source.getParent(); System.out.println(parentPath);
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream(source);
zipIn = new ZipInputStream(fis);
ZipEntry entry = null;
while((entry = zipIn.getNextEntry()) != null){
File file = new File(parentPath + "\\" + entry.getName()); //为了空目录的出现
if(entry.isDirectory()){
file.mkdirs();
continue;
} File parentDir = file.getParentFile();
if(!parentDir.exists()){
parentDir.mkdirs();
}
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
int count = -1;
byte []buffer = new byte[1024];
while((count = zipIn.read(buffer, 0, buffer.length)) != -1){
bos.write(buffer, 0, count);
}
bos.flush();
bos.close();
fos.close();
}
zipIn.close();
}catch (Exception e) {
logger.error(e.getMessage(),e);
}finally{
try{
if(fis != null){
fis.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(fos != null){
fos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(bos != null){
bos.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
try{
if(zipIn != null){
zipIn.close();
}
}catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
}
Java压缩技术的学习的更多相关文章
- Java压缩技术(二) ZIP压缩——Java原生实现
原文:http://snowolf.iteye.com/blog/642298 去年整理了一篇ZLib算法Java实现(Java压缩技术(一) ZLib),一直惦记却没时间补充.今天得空,整理一下ZI ...
- 一位资深程序员大牛给予Java提升技术的学习路线建议
15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 ...
- java 压缩技术
package zip; import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStr ...
- Java压缩技术(三) ZIP解压缩——Java原生实现
原文:http://snowolf.iteye.com/blog/642492 JavaEye的朋友跟我说:“你一口气把ZIP压缩和解压缩都写到一个帖子里,我看起来很累,不如分开好阅读”.ok,面向读 ...
- Java压缩技术(一) ZLib
原文:http://snowolf.iteye.com/blog/465433 有关ZLib可参见官方主页 http://www.zlib.net/ ZLib可以简单的理解为压缩/解压缩算法,它与ZI ...
- Java后端实现图片压缩技术
今天来说说图片压缩技术,为什么要使用图片压缩,图片上传不就完事了吗?对的,这在几年前可以这么说,因为几年前还没有现在这么大的并发,也没有现在这么关注性能. 如今手机很多,很多人都是通过手机访问网络或者 ...
- Java多线程技术学习笔记(二)
目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...
- 如何才能够系统地学习Java并发技术?
微信公众号[Java技术江湖]一位阿里Java工程师的技术小站 Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容. 这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些 ...
- 2020年Java程序员应该学习的10大技术
对于Java开发人员来说,最近几年的时间中,Java生态诞生了很多东西.每6个月更新一次Java版本,以及发布很多流行的框架,如Spring 5.Spring Security 5和Spring Bo ...
随机推荐
- Table XXX is marked as crashed and should be repaired问题
数据表出错了,查询数据获取不到了. 尝试一 重启mysql service mysqld restart 没用,重启并没有把表修复掉 尝试二 check table vicidial_list;rep ...
- LSH、ITQ、SKLSH图像检索实验实现(包含源码下载地址)
原文来自我的独立blog:http://www.yuanyong.org/blog/cv/lsh-itq-sklsh-compliment 这两天寻找idea,想来思去也没想到好点的方法,于是把前段时 ...
- QT 绘制按钮 paintEvent enterEvent leaseEvent mouseEvent
案例2:绘制按钮 main.cpp #include<QApplication> #include “demoWidget.h” int main(int args , int arg ...
- Centos 6.8下安装LBP2900打印机驱动
今天第一次在Linux下面安装LBP2900的驱动程序,在安装的过程中出现了不少的问题,不过问题最终还是解决了. 1.下载LBP2900的Linux驱动程序: Linux_LBP2900_CAPT_P ...
- vim 多窗口编辑
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- 将ImageView中的图片保存到本地相冊
private void SaveImageToSysAlbum() { if (FileUtil.isSdCardExist()) { BitmapDrawable bmpDrawable = (B ...
- ARM64调试环境
自从上一次ZCTF做了一道ARM64的逆向题目后,我决定记录下利用qemu搭建ARM64的环境的过程,以后肯定会遇到更多ARM平台下的Reverse和PWN. 一 安装QEMU 我要模拟的是64位的A ...
- spring boot 中文文档
https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/content/VII.%20Spring%20Boot%20CLI/index. ...
- "margin塌陷现象"div盒子嵌套盒子外边距合并现象
问题描述:原型大概是“一个div嵌套了两个 div,给main设定了background="pink" ,header1设定background=“red” .header2 设定 ...
- C#运算符的优先级
在C#中,一共有38个常用的运用符,根据它们所执行运算的特点和它们的优先级,为了便于记忆,我将它们归为七个等级:1.单元运算符和括号.2.常规算术运算符.3.位移运算符.4.比较运算符.5.逻辑运算符 ...