Search code examples
javatruezip

How to copy files using TrueZip TPath?


As a follow-up to Convert .tar.gz file to .zip using TrueZip? how does one copy the contents of one compressed file into another using TrueZip? When I invoke:

TPath sourceFile = new TPath("c:/foo.zip");
TPath targetFile = new TPath("c:/bar.jar");
Files.copy(sourceFile, targetFile, StandardCopyOption.COPY_ATTRIBUTES);

I get:

java.io.FileNotFoundException: C:\foo.zip (expected FILE - is DIRECTORY)
    at de.schlichtherle.truezip.nio.file.TFileSystemProvider.copy(TFileSystemProvider.java:397)
    at de.schlichtherle.truezip.nio.file.TFileSystemProvider.copy(TFileSystemProvider.java:364)
    at java.nio.file.Files.copy(Files.java:1219)

The thing is, I know for a fact that c:/foo.zip is an existing file, not a directory.

  1. Why am I getting this error?
  2. How am I supposed to convert a ZIP file to a JAR file using TPaths?
  3. Does TPath require unmounting like TFile does?

Solution

  • Answering my own question... Please note I figured this out by trial and error so I could be wrong on some of the points:

    1. Archives are treated as directories. Files.copy(archive, archive) is essentially trying to copy one directory to another. Files.copy(Path, Path) is made for copying a single file, not for copying directories recursively.

    2. Now that we know archives are treated as directories we simply copy files from one directory into another:

    Files.walkFileTree(sourceFile, new SimpleFileVisitor<Path>()
    {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
        {
            Files.copy(file, targetFile.resolve(sourceFile.relativize(file)), 
                StandardCopyOption.COPY_ATTRIBUTES);
            return super.visitFile(file, attrs);
        }
    });
    

    3. Yes, you can use: targetFile.getFileSystem().sync(FsSyncOptions.UMOUNT);