ma piękny sposób obsługi plików zip, traktując je jako systemy plików. Dzięki temu możemy traktować zawartość pliku ZIP jak zwykłe pliki. W ten sposób skompresowanie całego folderu można uzyskać, po prostu za pomocą Files.copy
, aby skopiować wszystkie pliki do pliku zip. Ponieważ podfoldery również mają być kopiowane, potrzebujemy użytkownika:Załadowanie ogromnego folderu za pomocą pliku ZipFileSystem powoduje, że pakiet OutOfMemoryError
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;
}
}
To jest prosty "kopia katalogowa rekurencyjnie" odwiedzający. Służy do rekurencyjnego kopiowania katalogu. Jednak z ZipFileSystem
, możemy również użyć go skopiować katalog w pliku zip, tak:
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));
}
To jest to, co nazywam elegancki sposób skompresowanie cały folder. Jednak podczas korzystania z tej metody w dużym folderze (około 3 GB) otrzymuję OutOfMemoryError
(przestrzeń sterty). Podczas korzystania ze zwykłej biblioteki obsługi zip, ten błąd nie jest zgłaszany. Wydaje się więc, że sposób, w jaki ZipFileSystem
obsługuje kopie, jest bardzo nieefektywny: zbyt wiele plików, które mają być zapisane, jest przechowywane w pamięci, więc występuje OutOfMemoryError
.
Dlaczego tak się dzieje? Czy używanie ZipFileSystem
generalnie jest uważane za nieefektywne (jeśli chodzi o zużycie pamięci), czy też robię coś nie tak?
Niestety, ale ta odpowiedź nie pomaga w ogóle. 1) Wiem, jak zwiększyć wielkość sterty, to nie jest pytanie. 2) Co to jest "system plików pamięci" a "system plików na dysku"? 3) Metoda nie jest równoległa, jak powinieneś zobaczyć z kodu – gexicide
@gexicide Proszę sprawdzić moją odpowiedź i jeśli to rozwiąże twój problem (jak to zrobił dla innych), proszę oznaczyć ją jako poprawną odpowiedź. Dzięki. –