使用 java.util.zip.ZipOutputStream 时 zip 文件中的目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/740375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
directories in a zip file when using java.util.zip.ZipOutputStream
提问by Bala
Lets say I have a file t.txt, a directory t and another file t/t2.txt. If I use the linux zip utility "zip -r t.zip t.txt t", I get a zip file with the following entries in them (unzip -l t.zip):
假设我有一个文件 t.txt、一个目录 t 和另一个文件 t/t2.txt。如果我使用 linux zip 实用程序“zip -r t.zip t.txt t”,我会得到一个包含以下条目的 zip 文件(unzip -l t.zip):
Archive: t.zip
Length Date Time Name
-------- ---- ---- ----
9 04-11-09 09:11 t.txt
0 04-11-09 09:12 t/
15 04-11-09 09:12 t/t2.txt
-------- -------
24 3 files
If I try to replicate that behavior with java.util.zip.ZipOutputStream and create a zip entry for the directory, java throws an exception. It can handle only files. I can create a t/t2.txt entry in the zip file and add use the t2.txt file contents to it but I can't create the directory. Why is that?
如果我尝试使用 java.util.zip.ZipOutputStream 复制该行为并为该目录创建一个 zip 条目,java 将引发异常。它只能处理文件。我可以在 zip 文件中创建 at/t2.txt 条目并将使用 t2.txt 文件内容添加到其中,但我无法创建目录。这是为什么?
回答by John Ellinwood
ZipOutputStream
canhandle empty directories by adding a forward-slash /
after the folder name. Try (from)
ZipOutputStream
可以通过/
在文件夹名称后添加正斜杠来处理空目录。尝试(来自)
public class Test {
public static void main(String[] args) {
try {
FileOutputStream f = new FileOutputStream("test.zip");
ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(f));
zip.putNextEntry(new ZipEntry("xml/"));
zip.putNextEntry(new ZipEntry("xml/xml"));
zip.close();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
回答by John Ellinwood
You can add "/" at the end of folder name. Just use the following command:
您可以在文件夹名称的末尾添加“/”。只需使用以下命令:
zip.putNextEntry(new ZipEntry("xml/"));
回答by user769087
Just go through the source of java.util.zip.ZipEntry. It treats a ZipEntry as directory if its name ends with "/" characters. Just suffix the directory name with "/".
只需查看 java.util.zip.ZipEntry 的源代码。如果名称以“/”字符结尾,则将 ZipEntry 视为目录。只需在目录名后缀“/”。
Check this example for zipping just the empty directories, http://bethecoder.com/applications/tutorials/showTutorials.action?tutorialId=Java_ZipUtilities_ZipEmptyDirectory
检查此示例以仅压缩空目录,http://bethecoder.com/applications/tutorials/showTutorials.action?tutorialId=Java_ZipUtilities_ZipEmptyDirectory
Good luck.
祝你好运。
回答by programmmer
Java Program to Zip(folders contains either empty or full ones)
Java Program to Zip(文件夹包含空的或完整的)
public class ZipUsingJavaUtil {
/*
* Zip function zip all files and folders
*/
@Override
@SuppressWarnings("finally")
public boolean zipFiles(String srcFolder, String destZipFile) {
boolean result = false;
try {
System.out.println("Program Start zipping the given files");
/*
* send to the zip procedure
*/
zipFolder(srcFolder, destZipFile);
result = true;
System.out.println("Given files are successfully zipped");
} catch (Exception e) {
System.out.println("Some Errors happned during the zip process");
} finally {
return result;
}
}
/*
* zip the folders
*/
private void zipFolder(String srcFolder, String destZipFile) throws Exception {
ZipOutputStream zip = null;
FileOutputStream fileWriter = null;
/*
* create the output stream to zip file result
*/
fileWriter = new FileOutputStream(destZipFile);
zip = new ZipOutputStream(fileWriter);
/*
* add the folder to the zip
*/
addFolderToZip("", srcFolder, zip);
/*
* close the zip objects
*/
zip.flush();
zip.close();
}
/*
* recursively add files to the zip files
*/
private void addFileToZip(String path, String srcFile, ZipOutputStream zip, boolean flag) throws Exception {
/*
* create the file object for inputs
*/
File folder = new File(srcFile);
/*
* if the folder is empty add empty folder to the Zip file
*/
if (flag == true) {
zip.putNextEntry(new ZipEntry(path + "/" + folder.getName() + "/"));
} else { /*
* if the current name is directory, recursively traverse it
* to get the files
*/
if (folder.isDirectory()) {
/*
* if folder is not empty
*/
addFolderToZip(path, srcFile, zip);
} else {
/*
* write the file to the output
*/
byte[] buf = new byte[1024];
int len;
FileInputStream in = new FileInputStream(srcFile);
zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
while ((len = in.read(buf)) > 0) {
/*
* Write the Result
*/
zip.write(buf, 0, len);
}
}
}
}
/*
* add folder to the zip file
*/
private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception {
File folder = new File(srcFolder);
/*
* check the empty folder
*/
if (folder.list().length == 0) {
System.out.println(folder.getName());
addFileToZip(path, srcFolder, zip, true);
} else {
/*
* list the files in the folder
*/
for (String fileName : folder.list()) {
if (path.equals("")) {
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false);
} else {
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, false);
}
}
}
}
}
回答by chenop
Like others said here to add empty directory add "/" to the directory name. Pay attention NOT to add File.separator (equals to "\") which actually add an empty file to the zip.
像其他人说的在这里添加空目录在目录名称中添加“/”。注意不要添加 File.separator(等于“\”),它实际上将一个空文件添加到 zip 中。
It took me a while to understand what was my mistake - hope I save other some time...
我花了一段时间才明白我的错误是什么 - 希望我能节省一些时间......
回答by Joy Joseph
String dir = "E:\Infor\Marketing\JobLog\Cloud_MomBuild_NoMirror";
String dir = "E:\Infor\Marketing\JobLog\Cloud_MomBuild_NoMirror";
public void downloadAsZip() throws IOException {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteOutputStream);
Path folderPath = Paths.get(dir);
String folderName = "Output";
for (File file : folderPath.toFile().listFiles()) {
String path = folderName + "/" + file.getName();
if (file.isDirectory()) {
writeFolderToZip(zipOutputStream, file, path);
} else {
writeFileToZip(zipOutputStream, file, path);
}
}
}
public void writeFileToZip(ZipOutputStream zipOutputStream, File file, String path) throws IOException {
zipOutputStream.putNextEntry(new ZipEntry(path));
FileInputStream fileInputStream = new FileInputStream(file);
IOUtils.copy(fileInputStream, zipOutputStream);
fileInputStream.close();
zipOutputStream.closeEntry();
}
public void writeFolderToZip(ZipOutputStream zipOutputStream, File dir, String path) throws IOException {
for (File file : dir.listFiles()) {
String dirPath = path + "/" + file.getName();
if (file.isDirectory()) {
writeFolderToZip(zipOutputStream, file, dirPath);
} else {
writeFileToZip(zipOutputStream, file, dirPath);
}
}
}