请查看以下代码。
public void startCompress(String path,String fileName,String outputLocation,int compressType,int filSize) throws Exception
{
System.out.println("Input Location: "+path);
System.out.println("Output Location: "+outputLocation);
System.out.println(compressType);
byte[] bs=new byte[filSize];
System.out.println(filSize);
FileOutputStream fos=new FileOutputStream(outputLocation+"/test.zip");
System.out.println(fos.toString());
ZipOutputStream zos=new ZipOutputStream(fos);
ZipEntry ze = new ZipEntry(fileName);
zos.putNextEntry(ze);
FileInputStream inputStream=new FileInputStream(path);
int len;
while((len=inputStream.read(bs))>0){
zos.write(bs, 0, len);
}
inputStream.close();
zos.closeEntry();
zos.close();
}
在上面的代码中,我们使用java.util.zip
包压缩文件。但我们有一个问题。也就是说,如果我们选择多个文件,则只压缩一个文件。如果我们选择一个文件夹,压缩就不起作用了。
如何解决此问题以压缩文件,文件,文件夹,文件夹甚至嵌套文件夹? Java zip包支持.zip,.tar,.tarGz和tarZ。所以解决方案不应该只限于.zip扩展名。
答案 0 :(得分:2)
java的zip库不能用于压缩文件夹,例如压缩文件夹。
如果输入是文件夹或文件,则需要自己进行测试。如果是文件 - 将其添加到zip中。如果是文件夹 - 迭代文件夹并将每个文件添加到zip。对于子文件夹来说是一样的。要向Zip添加多个文件,您需要为每个文件创建ZipEntry。
您可以尝试使用适合我的代码:
public static void zip(File directory, File zipfile) throws IOException {
URI base = directory.toURI();
Deque<File> queue = new LinkedList<File>();
queue.push(directory);
OutputStream out = new FileOutputStream(zipfile);
Closeable res = out;
try {
ZipOutputStream zout = new ZipOutputStream(out);
res = zout;
while (!queue.isEmpty()) {
directory = queue.pop();
for (File kid : directory.listFiles()) {
String name = base.relativize(kid.toURI()).getPath();
if (kid.isDirectory()) {
queue.push(kid);
name = name.endsWith("/") ? name : name + "/";
zout.putNextEntry(new ZipEntry(name));
} else {
zout.putNextEntry(new ZipEntry(name));
copy(kid, zout);
zout.closeEntry();
}
}
}
} finally {
res.close();
}
}
答案 1 :(得分:1)
更新自this answer,修复了已添加到其自己目录中的每个文件的问题。也更好地支持Windows资源管理器。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Test {
public static void main(String agrs[]) {
ZipUtils appZip = new ZipUtils();
appZip.zipIt(new File(source directory), new File(dest zip));
}
public static class ZipUtils {
private final List<File> fileList;
private List<String> paths;
public ZipUtils() {
fileList = new ArrayList<>();
paths = new ArrayList<>(25);
}
public void zipIt(File sourceFile, File zipFile) {
if (sourceFile.isDirectory()) {
byte[] buffer = new byte[1024];
FileOutputStream fos = null;
ZipOutputStream zos = null;
try {
// This ensures that the zipped files are placed
// into a folder, within the zip file
// which is the same as the one been zipped
String sourcePath = sourceFile.getParentFile().getPath();
generateFileList(sourceFile);
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(fos);
System.out.println("Output to Zip : " + zipFile);
FileInputStream in = null;
for (File file : this.fileList) {
String path = file.getParent().trim();
path = path.substring(sourcePath.length());
if (path.startsWith(File.separator)) {
path = path.substring(1);
}
if (path.length() > 0) {
if (!paths.contains(path)) {
paths.add(path);
ZipEntry ze = new ZipEntry(path + "/");
zos.putNextEntry(ze);
zos.closeEntry();
}
path += "/";
}
String entryName = path + file.getName();
System.out.println("File Added : " + entryName);
ZipEntry ze = new ZipEntry(entryName);
zos.putNextEntry(ze);
try {
in = new FileInputStream(file);
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
} finally {
in.close();
}
}
zos.closeEntry();
System.out.println("Folder successfully compressed");
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
protected void generateFileList(File node) {
// add file only
if (node.isFile()) {
fileList.add(node);
}
if (node.isDirectory()) {
File[] subNote = node.listFiles();
for (File filename : subNote) {
generateFileList(filename);
}
}
}
}
}
答案 2 :(得分:1)
这是我的解决方案,它使用新的java.nio包。只需调用zipDir,即可获得该目录的路径。它将在同一位置创建一个zip文件,但称为<directory>.zip
。
private static Path buildPath(final Path root, final Path child) {
if (root == null) {
return child;
} else {
return Paths.get(root.toString(), child.toString());
}
}
private static void addZipDir(final ZipOutputStream out, final Path root, final Path dir) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path child : stream) {
Path entry = buildPath(root, child.getFileName());
if (Files.isDirectory(child)) {
addZipDir(out, entry, child);
} else {
out.putNextEntry(new ZipEntry(entry.toString()));
Files.copy(child, out);
out.closeEntry();
}
}
}
}
public static void zipDir(final Path path) throws IOException {
if (!Files.isDirectory(path)) {
throw new IllegalArgumentException("Path must be a directory.");
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path.toString() + ".zip"));
try (ZipOutputStream out = new ZipOutputStream(bos)) {
addZipDir(out, path.getFileName(), path);
}
}