该java.nio
软件包通过将zip文件视为文件系统,具有处理zip文件的优美方法。这使我们能够像对待普通文件一样对待zip文件内容。因此,仅通过Files.copy
将所有文件复制到zip文件中即可压缩整个文件夹。由于也要复制子文件夹,因此我们需要一个访问者:
private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
private final Path targetPath;
private Path sourcePath = null;
public CopyFileVisitor(Path targetPath) {
this.targetPath = targetPath;
}
@Override
public FileVisitResult preVisitDirectory(final Path dir,
final BasicFileAttributes attrs) throws IOException {
if (sourcePath == null) {
sourcePath = dir;
} else {
Files.createDirectories(targetPath.resolve(sourcePath
.relativize(dir).toString()));
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(final Path file,
final BasicFileAttributes attrs) throws IOException {
Files.copy(file,
targetPath.resolve(sourcePath.relativize(file).toString()), StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}
}
这是一个简单的“递归复制目录”访问者。它用于递归复制目录。但是,使用ZipFileSystem
,我们还可以使用它将目录复制到zip文件中,如下所示:
public static void zipFolder(Path zipFile, Path sourceDir) throws ZipException, IOException
{
// Initialize the Zip Filesystem and get its root
Map<String, String> env = new HashMap<>();
env.put("create", "true");
URI uri = URI.create("jar:" + zipFile.toUri());
FileSystem fileSystem = FileSystems.newFileSystem(uri, env);
Iterable<Path> roots = fileSystem.getRootDirectories();
Path root = roots.iterator().next();
// Simply copy the directory into the root of the zip file system
Files.walkFileTree(sourceDir, new CopyFileVisitor(root));
}
这就是我称为压缩整个文件夹的一种优雅方式。但是,在巨大的文件夹(大约3
GB)上使用此方法时,会收到OutOfMemoryError
(堆空间)。当使用常规的zip处理库时,不会引发此错误。因此,似乎ZipFileSystem
处理副本的方式效率很低:太多要写入的文件保留在内存中,因此OutOfMemoryError
发生了。
为什么会这样呢?是ZipFileSystem
通常认为使用效率低下(就内存消耗而言),还是我在这里做错了什么?
我查看了ZipFileSystem.java,我相信找到了内存消耗的来源。默认情况下,该实现将ByteArrayOutputStream
用作压缩文件的缓冲区,这意味着它受分配给JVM的内存量的限制。
我们可以使用一个(未记录的)环境变量来使实现使用临时文件("useTempFile"
)。它是这样的:
Map<String, Object> env = new HashMap<>();
env.put("create", "true");
env.put("useTempFile", Boolean.TRUE);
此处有更多详细信息:http
:
//www.docjar.com/html/api/com/sun/nio/zipfs/ZipFileSystem.java.html,有趣的行是96、1358和1362。
我尝试将xlsx读入数据帧: 我收到这个: 回溯(最近一次调用last):文件“C:\Users\Administrator\eclipse workspace\Reports\GOW\Report.py”,第44行,df=pd。读取excel('C:\Users\Administrator\Downloads\reportdata.xlsx') 文件“C:\Users\Administrator
首先,我没有看到任何其他问题可以“直接”帮助我解决问题,这就是为什么我决定创建一个新的问题。 以下代码被编程为解压缩多个文件和文件夹。 这段代码工作正常,但有一个重要的错误:它解压缩文件夹,但不是像这样显示它们: 文件1。txt 它显示了这一点: file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt 我做错了什么?
问题内容: 我正在尝试压缩包含子文件夹的文件夹。尝试压缩名为10-18-2010_4D的文件夹。以上程序以以下异常结束。请提供有关如何解决此问题的建议。 问题答案: 您需要检查文件是否为目录,因为您无法将目录传递给zip方法。 看一下该页面,该页面显示了如何递归压缩给定目录。
问题内容: 我尝试解压缩150个zip文件。所有zip文件都使用不同的名称,它们都分散在一个大文件夹中,该文件夹分为许多子文件夹和子子文件夹。我想将每个存档提取到与原始zip文件名相同名称的单独文件夹中,与原始zip文件位于同一位置。我的代码是: 我运行代码后,什么都没有发生。在此先感谢您的任何帮助。 问题答案: 更新: 最后,这段代码对我有用:
问题内容: 假设我具有以下目录结构。 一月份内部有两个excel文件,分别是A.xls和B.xls。在很多地方,都有关于如何使用zip文件进行压缩的文章。但是,我要压缩的文件夹一月自身内部报告文件夹,这样既 月份 和 january.zip 将出席内部报告。( 这意味着当我解压缩january.zip文件时,我应该得到january文件夹 )。 谁能给我提供使用进行此操作的代码。请让我知道通过使用
假设我有以下目录结构。 一月份内,假设有两个excel文件,分别是A.xls和B.xls。有很多地方都写过关于如何使用