如果是文件目录,则
ZipEntry zipEntry=new ZipEntry(basePath + System.getProperties().getProperty(“file.separator”));
zipEntry.setUnixMode(0755);//解决linux乱码
如果是文件,则
ZipEntry zipEntry=new ZipEntry(base);
zipEntry.setUnixMode(0644);//解决linux乱码
然后在输出时强制设置编码:
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
zipFileName));
out.setEncoding(“GBK”);//解决linux乱码
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import lombok.extern.slf4j.Slf4j;
/**
*
* @author zhanghuikun
*/
@Slf4j
public class Zip {
static final int BUFFER = 1024;
public Zip() {
}
static {
System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding"));
}
private static void compress(File file, ZipOutputStream out, String basedir) {
if (file.isDirectory()) {
compressDirectory(file, out, basedir);
} else {
compressFile(file, out, basedir);
}
}
/**
* Compress a directory
*/
private static void compressDirectory(File dir, ZipOutputStream out, String basedir) {
if (!dir.exists()) {
return;
}
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
compress(files[i], out, basedir + dir.getName() + "/");
}
}
/**
* Compress a file
*/
private static void compressFile(File file, ZipOutputStream out, String basedir) {
if (!file.exists()) {
return;
}
try {
String encoding = System.getProperty("file.encoding");
String decName = new String(file.getName().getBytes(encoding), StandardCharsets.UTF_8);
String encName = new String(decName.getBytes(StandardCharsets.UTF_8), encoding);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
basedir = basedir.substring(basedir.split("/")[0].length() + 1, basedir.length());
ZipEntry entry = new ZipEntry(basedir + encName);
entry.setUnixMode(644);
out.putNextEntry(entry);
int count = -1;
byte[] data = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
bis.close();
} catch (Exception e) {
log.error("compressFile {} error", file.getName(), e);
}
}
/**
* * java压缩 linux下中文文件名乱码
* *
*
* @param srcPathName
* @param zipFileName
*/
public static void zip(String srcPathName, String zipFileName) {
File file = new File(srcPathName);
File zipFile = new File(zipFileName);
if (!file.exists()) {
return;
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new CRC32());
ZipOutputStream out = new ZipOutputStream(cos);
// Set the file name encoding method
out.setEncoding(System.getProperty("sun.jnu.encoding"));
String basedir = "";
compress(file, out, basedir);
out.close();
} catch (Exception e) {
log.error("zip {} error", srcPathName, e);
}
}
/**
* zip解压
* only DEFLATED entries can have EXT descriptor异常的解决方案请参考
* https://stackoverflow.com/questions/47208272/android-zipinputstream-only-deflated-entries-can-have-ext-descriptor
*
* @param inputFile 待解压文件名
* @param destDirPath 解压路径
* @param charset 编码
*/
public static void zipUncompress(String inputFile, String destDirPath, Charset charset) throws Exception {
unzip(new File(inputFile), new File(destDirPath), charset.name());
}
public static void unzip(File zipFile, File destDir, String encoding) throws IOException, ArchiveException {
String destDirectory = destDir.getAbsolutePath();
try (ArchiveInputStream i = new ZipArchiveInputStream(new
FileInputStream(zipFile), encoding, false, true)) {
ArchiveEntry entry = null;
while ((entry = i.getNextEntry()) != null) {
if (!i.canReadEntryData(entry)) {
continue;
}
String name = destDirectory + File.separator + new String(entry.getName().getBytes(encoding),
StandardCharsets.ISO_8859_1);
File f = new File(name);
if (entry.isDirectory()) {
if (!f.isDirectory() && !f.mkdirs()) {
log.error("failed to create directory {}", f);
}
} else {
File parent = f.getParentFile();
if (!parent.isDirectory() && !parent.mkdirs()) {
log.error("failed to create directory {}", parent);
}
try (OutputStream o = Files.newOutputStream(f.toPath())) {
IOUtils.copy(i, o);
}
}
}
}
}
}