gpt4 book ai didi

Java 将文件复制到 zip AccessDeniedException

转载 作者:行者123 更新时间:2023-12-01 17:52:29 24 4
gpt4 key购买 nike

描述:

我在 Java 8 中创建了一个 ZIP 文件,并尝试将一个目录及其所有子文件和目录复制到该 zip 文件中。

   Path directory = Paths.get("P:\Java\Test\backups\test.zip");
// path to the world;
Path world = Paths.get("P:\Java\Test\world");

[...]

// Create a map which tells the file system to create a new file if it doesn't exist
ImmutableMap immutableMap = ImmutableMap.of("create", String.valueOf(Files.notExists(this.directory)));

// Get a file system provider which is capable of creating a ZIP file
FileSystemProvider zipProvider = FileSystemProvider.installedProviders().stream()
.filter(provider -> provider.getScheme().equals("jar")).findFirst().get();

// Create the file system
try (FileSystem fs = zipProvider.newFileSystem(this.directory, immutableMap)) {

try {
Files.walk(this.world).forEach((Path sourcePath) -> {
try {
CopyOption[] option = new CopyOption[] {
StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES
};
Path destination = this.directory.resolve(this.world.relativize(sourcePath));
Files.copy(sourcePath, destination,option);
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}

问题:

每当我添加行 Files.copy 将我的目录以及所有子目录和子文件复制到 zip 文件中时,我都会收到以下异常:java.nio。 file.AccessDeniedException:.\backups\test.zip

控制台输出:

在下面的堆栈跟踪中,我将类调用的行号更改为上面发布的代码片段的行号,以提高可读性,除了对 ThreadBackup.run 方法的调用之外。它基本上是代码与其他一些但不相关的事物一起执行的方法。

java.nio.file.AccessDeniedException: .\backups\tests.zip
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileCopy.copy(WindowsFileCopy.java:231)
at sun.nio.fs.WindowsFileSystemProvider.copy(WindowsFileSystemProvider.java:278)
at java.nio.file.Files.copy(Files.java:1274)
at serverutilities.backups.ThreadBackups.lambda$createZipFile$1(ThreadBackups.java:24)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at serverutilities.backups.ThreadBackups.createZipFile(ThreadBackups.java:18)
at serverutilities.backups.ThreadBackups.run(ThreadBackups.java:56)
at java.lang.Thread.run(Thread.java:748)

java.nio.file.NoSuchFileException: P:\Java\Test\backups\test.zip
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:90)
at sun.nio.fs.WindowsLinkSupport.getRealPath(WindowsLinkSupport.java:259)
at sun.nio.fs.WindowsPath.toRealPath(WindowsPath.java:836)
at sun.nio.fs.WindowsPath.toRealPath(WindowsPath.java:44)
at com.sun.nio.zipfs.ZipFileSystemProvider.removeFileSystem(ZipFileSystemProvider.java:322)
at com.sun.nio.zipfs.ZipFileSystem.close(ZipFileSystem.java:305)
at serverutilities.backups.ThreadBackups.createZipFile(ThreadBackups.java:32)
at serverutilities.backups.ThreadBackups.run(ThreadBackups.java:56)
at java.lang.Thread.run(Thread.java:748)

我注意到,每当我调用 Files.copy 方法时,ZIP 文件甚至都没有创建或至少没有保存,因此 NoSuchFileException 之后抛出>AccessDeniedException 对于我尝试复制的每个目录和文件都会抛出。

最佳答案

我从未使用过 java.nio.file,但是一旦我必须处理此类任务,我就使用了 java.util.zip,它非常简单,仅用于从目录创建 zip 文件

尽管如此,如果您无法更改用于归档目录的内容,那么此解决方案不会有太大帮助,但示例代码带有一些解释:

  • 使用新的 ZipOutputStream 创建新的 ZIP 存档
  • 遍历将使用 Files.walk 压缩的文件树
  • 对于文件树的每个路径,打包条目。 ZipEntry 保存有关存档中单个文件的元数据

要使用它,只需使用 src 和目标.zip 的路径调用 packDir 方法

private static void packDir(Path src, Path dest) throws IOException {
try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(dest));
ZipOutputStream zo = new ZipOutputStream(out);
Stream<Path> dirStream = Files.walk(src)) {
dirStream.filter(p -> !p.equals(src)).forEach(path -> {
try {
packEntry(src, zo, path);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}

private static void packEntry(Path src, ZipOutputStream zo, Path path) throws IOException {
String name = src.relativize(path).toString().replace('\\', '/');
boolean isDir = Files.isDirectory(path);
if (isDir) {
name += "/";
}
ZipEntry e = new ZipEntry(name);
zo.putNextEntry(e);
if (!isDir) {
Files.copy(path, zo);
}
zo.closeEntry();
}

关于Java 将文件复制到 zip AccessDeniedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48468080/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com