我想要解压一个目录下的三个文件,其中一个是Excel两个是pdf文件,但是利用代码解压出来后Excel会损坏,文件大小比源文件小,pdf文件可以正常打开但是会损失一些莫名的画面
比如我的pdf是合同,里面竟然有字但是公司盖的章就没有了,这是代码问题!
解决办法:
我是同一个方法中先生成了3个文件紧接着就调用解压方法去解压这三个文件,其实这是不对的。
我们应该先关闭生成这3个文件的流,在close()的时候会自动调用flush()刷新缓冲区,这样子我们会保证文件的完整性。
这时候再调用解压缩文件的方法,至于解压缩的close就在解压缩方法中关闭即可!
最后提一嘴,在循环new一个流的时候,一定要在循环中close()!
关闭一个流就必须用一个try-catch,不要为了省事用一个try-catch关闭所有流,不然如果前面的流报错了,后面的流是无法关闭的!
解决问题之前我的代码步骤如下:
1.生成三个文件
2.解压缩
3.finally中关闭三个文件用到的应该关闭的流
解决问题之后我的步骤:
1.生成三个文件
2.不用finally,一个try-catch关闭一个流,关闭三个文件用到的所有流
3.调用解压缩方法(解压缩的流在解压缩方法中关闭)
下面是我查找资料找到的解压缩方法,需要的同学直接copy吧. ↓↓↓↓↓↓↓
/**
*
* @param sourceFilePath 需要压缩的文件夹
* @param zipFilePath 压缩包的存放位置
* @param fileName 压缩包名称
* @return
*/
// 不能压缩单独文件,文件夹中没有东西也不行!必须压缩一个文件夹,有特殊需要就自己修改一下代码。
public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) {
boolean flag = false;
File sourceFile = new File(sourceFilePath);
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
ZipOutputStream zos = null;
if (!sourceFile.exists()) {
} else {
try {
File zipFile = new File(zipFilePath + "/" + fileName + ".zip");
if (zipFile.exists()) {
return true;
} else {
File[] sourceFiles = sourceFile.listFiles();
if (null == sourceFiles || sourceFiles.length < 1) {
// System.out.println(”待压缩的文件目录:” + sourceFilePath + “里面不存在文件,无需压缩.”);
} else {
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte[] bufs = new byte[1024*10];
for (File file : sourceFiles) {
//创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(file.getName());
zos.setLevel(9);
zos.putNextEntry(zipEntry);
//读取待压缩的文件并写进压缩包里
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis, 1024 * 10);
int read = 0;
while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
zos.write(bufs, 0, read);
}
//一定在循环中关闭流,不然流会出现关闭不全的情况!!!
bis.close();
}
flag = true;
}
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
//关闭流,不要图省事,一定要一个try-catch对应关闭一个流!
//最后开的流最先关,就按照这个顺序关闭!不懂的看我代码顺序摸索一下。
//Buffered这种流如果里面包含了其他流
//比如我这段bis对象包含了fis,就只需要关闭bis流即可!
//因为它会调用fis的close(),会把自己的儿子也关了,这个你不用操心了!
try {
if (null != bis) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (null != zos) {
zos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return flag;
}