从ZIP存档中删除文件而不使用Java(首选)或Python
进行解压缩您好,
我使用包含数百个高度压缩文本文件的大型ZIP文件。当我解压缩ZIP文件时,它可能需要一段时间,并且很容易消耗多达20 GB的磁盘空间。我想从这些ZIP文件中删除某些文件,而不必解压缩和重新压缩我想要的文件。
当然,长期以来可以做到这一点,但效率非常低。
我更愿意在Java中这样做,但会考虑Python
答案 0 :(得分:3)
import java.util.*;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.*;
import java.nio.file.StandardCopyOption;
public class ZPFSDelete {
public static void main(String [] args) throws Exception {
/* Define ZIP File System Properies in HashMap */
Map<String, String> zip_properties = new HashMap<>();
/* We want to read an existing ZIP File, so we set this to False */
zip_properties.put("create", "false");
/* Specify the path to the ZIP File that you want to read as a File System */
URI zip_disk = URI.create("jar:file:/my_zip_file.zip");
/* Create ZIP file System */
try (FileSystem zipfs = FileSystems.newFileSystem(zip_disk, zip_properties)) {
/* Get the Path inside ZIP File to delete the ZIP Entry */
Path pathInZipfile = zipfs.getPath("source.sql");
System.out.println("About to delete an entry from ZIP File" + pathInZipfile.toUri() );
/* Execute Delete */
Files.delete(pathInZipfile);
System.out.println("File successfully deleted");
}
}
}
答案 1 :(得分:2)
我没有代码可以做到这一点,但基本的想法很简单,几乎可以翻译成任何语言。 ZIP文件布局只是一系列代表文件的块(标题后跟压缩数据),最后是一个只包含所有元数据的中心目录。这是过程:
有关ZIP文件结构的所有详细信息,请参阅http://en.wikipedia.org/wiki/ZIP_%28file_format%29。
最好的建议是,您可能希望将复制复制到另一个文件中,以防止在发生故障时丢失数据。
答案 2 :(得分:0)
好的,我想从www.javaer.org找到了一个潜在的解决方案。它肯定会删除zip中的文件,我认为它不会解压缩任何东西。这是代码:
public static void deleteZipEntry(File zipFile,
String[] files) throws IOException {
// get a temp file
File tempFile = File.createTempFile(zipFile.getName(), null);
// delete it, otherwise you cannot rename your existing zip to it.
tempFile.delete();
tempFile.deleteOnExit();
boolean renameOk=zipFile.renameTo(tempFile);
if (!renameOk)
{
throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
}
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String name = entry.getName();
boolean toBeDeleted = false;
for (String f : files) {
if (f.equals(name)) {
toBeDeleted = true;
break;
}
}
if (!toBeDeleted) {
// Add ZIP entry to output stream.
zout.putNextEntry(new ZipEntry(name));
// Transfer bytes from the ZIP file to the output file
int len;
while ((len = zin.read(buf)) > 0) {
zout.write(buf, 0, len);
}
}
entry = zin.getNextEntry();
}
// Close the streams
zin.close();
// Compress the files
// Complete the ZIP file
zout.close();
tempFile.delete();
}
答案 3 :(得分:0)
是的,JAVA可以使用名为 TRUEZIP 的库。
TrueZIP是一个基于Java的虚拟文件系统(VFS),它支持客户端 用于执行CRUD(创建,读取,更新,删除)操作的应用程序 在归档文件上,就像它们是虚拟目录一样,即使是嵌套的 多线程环境中的归档文件
请参阅以下链接以获取更多信息 https://truezip.java.net/
答案 4 :(得分:-4)
这可能是旧的,但这是一种方式。它确实有效,因为我经常使用它并且工作正常。
public boolean deleteFile(String zip_dir, String subfile){
delete(new File(zipdir, subfile));
}
private void delete(File file)
{
if(file == null || !file.exists())
return;
if(file.isFile())
{
file.delete();
return;
}
File children[] = file.listFiles();
for(int i = 0; i < children.length; i++)
{
File child = children[i];
if(child.isFile())
child.delete();
else
delete(child);
}
file.delete();
}