如何处理名称带有重音符号的ZIP文件条目?

时间:2017-11-23 00:37:01

标签: java file-io zip

我有一个简单的文件系统复制例程,它会在基于ZIP的文件系统中遇到麻烦。我的代码相对通用,因为它没有专门引用ZIP类,即。它使用FileSystemFiles.walkFileTree()Files.copy()

大多数情况下,我的代码按预期工作,即。将ZIP文件安全地复制(解压缩)到目标目录中。当其中一个ZIP条目名称中包含异常字符时,它会中断。我没有异常的精确定义,但它似乎是带有重音的字符,例如。 é

这是我的代码的重要部分。 copyFileSystem() 遍历通过文件系统,并使用FileCopyVisitor逐个复制每个文件。 (我这样做,所以我可以报告整个副本的进度 - 这个代码没有显示。)

public static boolean copyFileSystem(File src, File dest)
{
    boolean success = false;
    try (FileSystem fs = FileSystems.newFileSystem(src.toPath(), null))
    {
        Path root = fs.getPath("/");
        Files.walkFileTree(root, new FileCopyVisitor(dest));
        success = true;
    }
    catch (IOException | RuntimeException e)
    {
        LOG.error("Error copying file system", e);
    }
    return success;
}

class FileCopyVisitor implements FileVisitor<Path>
{
    public FileVisitResult visitFile(Path src, BasicFileAttributes attrs)
        throws IOException
    {
        File dest = new File(destinationDirectory, src.toString()); // <<==== error is here
        Files.copy(src, dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
        return FileVisitResult.CONTINUE;
    }
}

问题是调用src.toString()中的visitFile()来查找要复制的文件的名称。如果FileSystemZipFileSystem,则srcZipPath。当文件名包含重音时,对toString()的调用失败,其中IllegalArgumentException带有(令人沮丧的简短)消息MALFORMED[1]。 (当PathFile时,src.toFile()不支持使用src代替ZipPath。{/ p>

我试图通过完全避免调用toString()来解决这个问题,因此:

Path dest = destinationDirectory.toPath().resolve(src);

然而,这会产生ProviderMismatchException,大概是因为目标目录是Windows文件系统,而src属于ZipFileSystem

我确实设法使用反射解决了这个问题。也就是说,如果src.toString()引发异常,那么我会检查src是否为ZipPath,如果是,请使用反射来访问其隐藏的私有path字段文件名。我想我们都同意这是一个坏事 TM

有没有人对更好的处理方法有什么建议?

0 个答案:

没有答案