public static void main(String[] args) throws IOException {
   Path pIn = FileSystems.getDefault().getPath(args[0]);
   Path pOut = FileSystems.getDefault().getPath(args[1]);
   ByteChannel in = Files.newByteChannel(pIn, StandardOpenOption.READ);
   ByteChannel out =
       Files.newByteChannel(pOut, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
   ByteBuffer bb = ByteBuffer.allocate(BUFFER_SIZE);
   int nb = 0;
   while ((nb = in.read(bb)) != -1) {
     bb.flip();
     while (bb.hasRemaining()) {
       byte b = bb.get();
       ByteBuffer w;
       if (b == CONST) {
         byte[] arr = {b, b};
         w = ByteBuffer.wrap(arr);
       } else {
         byte[] arr = {b};
         w = ByteBuffer.wrap(arr);
       }
       out.write(w);
     }
     bb.clear();
   }
   in.close();
   out.close();
 }
    @Override
    public ByteBuffer next() {
      try {
        if (channel == null) {
          channel = Files.newByteChannel(filePath, StandardOpenOption.READ);
          LOG.debug("Opened file {}", filePath);
        }

        buffer.clear();
        int read = channel.read(buffer);
        if (read < 0) throw new NoSuchElementException();

        if (LOG.isDebugEnabled()) LOG.debug("Read {} bytes from {}", read, filePath);

        position += read;

        if (!hasNext()) close();

        buffer.flip();
        return buffer;
      } catch (NoSuchElementException x) {
        close();
        throw x;
      } catch (Exception x) {
        close();
        throw (NoSuchElementException) new NoSuchElementException().initCause(x);
      }
    }
Exemple #3
0
  public static void main(String args[]) {
    try {
      aServer asr = new aServer();

      // file channel.
      FileInputStream is = new FileInputStream("");
      is.read();
      FileChannel cha = is.getChannel();
      ByteBuffer bf = ByteBuffer.allocate(1024);
      bf.flip();

      cha.read(bf);

      // Path Paths
      Path pth = Paths.get("", "");

      // Files some static operation.
      Files.newByteChannel(pth);
      Files.copy(pth, pth);
      // file attribute, other different class for dos and posix system.
      BasicFileAttributes bas = Files.readAttributes(pth, BasicFileAttributes.class);
      bas.size();

    } catch (Exception e) {
      System.err.println(e);
    }

    System.out.println("hello ");
  }
    @SuppressWarnings("deprecation")
    public void testDummy() throws Exception {
      file = createTempDir("leftover").resolve("child.locked");
      openFile =
          Files.newByteChannel(
              file, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);

      parent = LuceneTestCase.getBaseTempDirForTestClass();
    }
Exemple #5
0
 public OutputStream newFileOutputStream(Path pathRelativeToProjectRoot, FileAttribute<?>... attrs)
     throws IOException {
   return new BufferedOutputStream(
       Channels.newOutputStream(
           Files.newByteChannel(
               getPathForRelativePath(pathRelativeToProjectRoot),
               ImmutableSet.<OpenOption>of(
                   StandardOpenOption.CREATE,
                   StandardOpenOption.TRUNCATE_EXISTING,
                   StandardOpenOption.WRITE),
               attrs)));
 }
 /*     */ public InputStream newInputStream(Path paramPath, OpenOption[] paramArrayOfOpenOption)
     /*     */ throws IOException
       /*     */ {
   /* 374 */ if (paramArrayOfOpenOption.length > 0) {
     /* 375 */ for (OpenOption localOpenOption : paramArrayOfOpenOption) {
       /* 376 */ if (localOpenOption != StandardOpenOption.READ)
         /* 377 */ throw new UnsupportedOperationException(
             "'" + localOpenOption + "' not allowed");
       /*     */ }
     /*     */ }
   /* 380 */ return Channels.newInputStream(Files.newByteChannel(paramPath, new OpenOption[0]));
   /*     */ }
Exemple #7
0
 private static void testSequential() throws IOException {
   long start = System.currentTimeMillis();
   try (SeekableByteChannel c = Files.newByteChannel(testFile, READ)) {
     while (true) {
       b.clear();
       int nbytes = c.read(b);
       if (nbytes <= 0) break;
     }
   }
   long end = System.currentTimeMillis();
   logger.info("testSequential {} ms", end - start);
 }
  public static void testZIP() throws Exception {
    // ==== Testing ZIP filesystem ===
    // two options to write - WRITE, WRITE + APPEND. Simple writes just rewrite current values
    URI uri = URI.create("jar:file:/test.zip!/test.txt");
    Map<String, String> env = new HashMap<>();
    env.put("create", "true");
    FileSystem zipfs = FileSystems.newFileSystem(uri, env);
    Path pz = zipfs.provider().getPath(uri);
    SeekableByteChannel s =
        Files.newByteChannel(
            pz,
            StandardOpenOption.WRITE,
            StandardOpenOption.CREATE,
            StandardOpenOption.APPEND); // , StandardOpenOption.APPEND);
    ByteBuffer bb = ByteBuffer.wrap("12345".getBytes());
    // s.truncate(0);//clear file - unsupported
    // s.position(0);//start position - unsupported
    s.write(bb);
    bb.position(2);
    s.write(bb);

    //		SeekableByteChannel s1 = Files.newByteChannel(pz, StandardOpenOption.WRITE,
    // StandardOpenOption.CREATE, StandardOpenOption.APPEND);//, StandardOpenOption.APPEND);
    //		s1.write(ByteBuffer.wrap("bb".getBytes()));
    //
    s.close();
    //		s1.close();
    s =
        Files.newByteChannel(
            pz,
            StandardOpenOption.READ,
            StandardOpenOption.CREATE); // , StandardOpenOption.APPEND);
    byte[] bbrb = new byte[(int) s.size()];
    s.read(ByteBuffer.wrap(bbrb));
    System.out.println(new String(bbrb)); // should be 12345345
    s.close();
  }
Exemple #9
0
 private static void testReopenAndSeek() throws IOException {
   long position = 0;
   long start = System.currentTimeMillis();
   while (true) {
     try (SeekableByteChannel c = Files.newByteChannel(testFile, READ)) {
       b.clear();
       c.position(position);
       int nbytes = c.read(b);
       if (nbytes <= 0) break;
       position += nbytes;
     }
   }
   long end = System.currentTimeMillis();
   logger.info("testReopenAndSeek {} ms", end - start);
 }
  private void combineChunk(Path downloadTo, Path path) throws Exception {
    final long start = System.currentTimeMillis();
    long bytes = 0;

    log.info("Writing {} to {}", path, downloadTo);

    try (WritableByteChannel wbs =
        Files.newByteChannel(
            downloadTo, EnumSet.of(StandardOpenOption.APPEND, StandardOpenOption.WRITE))) {
      try (FileChannel readChannel =
          FileChannel.open(
              path, EnumSet.of(StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE))) {
        bytes = readChannel.size();
        readChannel.transferTo(0, bytes, wbs);
      }
    }

    log.info("Finished writing {} bytes in {}", bytes, JavaUtils.duration(start));
  }
 public static void main(String[] args) {
   try (FileChannel fileChannel =
       (FileChannel)
           Files.newByteChannel(
               Paths.get(
                   "C:\\Users\\yangjunlin\\IdeaProjects\\WhileTrueCoding\\JavaBase\\doc\\test.txt"),
               StandardOpenOption.WRITE,
               StandardOpenOption.READ)) {
     ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10240);
     for (int i = 0; i < 10240; i++) {
       byteBuffer.put((byte) ('c'));
     }
     byteBuffer.rewind();
     fileChannel.write(byteBuffer);
     fileChannel.force(true);
   } catch (IOException e) {
     e.printStackTrace();
   }
 }
 // this method read every char at every 10 length position.
 private void executeRead() throws IOException {
   System.out.println("executeRead started");
   try (SeekableByteChannel channel =
       Files.newByteChannel(
           Paths.get("c:/temp/channelExample.txt"), EnumSet.of(StandardOpenOption.READ))) {
     ByteBuffer buffer = ByteBuffer.allocate(1);
     long position = 0;
     while (true) {
       buffer.clear();
       channel.position(position);
       if (channel.read(buffer) < 0) break;
       buffer.flip();
       System.out.println(
           "position : "
               + position
               + ", char : "
               + Charset.defaultCharset().decode(buffer)); // print chars from every 10 positions.
       position += 10;
     }
   }
 }
  public static void main(String args[]) {
    int count;
    Path filepath = null;

    // First, obtain a path to the file.
    try {
      filepath = Paths.get("test.txt");
    } catch (InvalidPathException e) {
      System.out.println("Path Error " + e);
      return;
    }

    // Next, obtain a channel to that file within a try-with-resources block.
    try (SeekableByteChannel fChan = Files.newByteChannel(filepath)) {

      // Allocate a buffer.
      ByteBuffer mBuf = ByteBuffer.allocate(128);

      do {
        // Read a buffer.
        count = fChan.read(mBuf);

        // Stop when end of file is reached.
        if (count != -1) {

          // Rewind the buffer so that it can be read.
          mBuf.rewind();

          // Read bytes from the buffer and show
          // them on the screen as characters.
          for (int i = 0; i < count; i++) System.out.print((char) mBuf.get());
        }
      } while (count != -1);

      System.out.println();
    } catch (IOException e) {
      System.out.println("I/O Error " + e);
    }
  }
 public void testWindows() throws Exception {
   // ==== Testing Windows filesystem ===
   // two options to write - WRITE, WRITE + APPEND. Simple writes just rewrite current values
   SeekableByteChannel s =
       Files.newByteChannel(
           Paths.get("test.txt"),
           StandardOpenOption.WRITE,
           StandardOpenOption.READ,
           StandardOpenOption.CREATE); // , StandardOpenOption.APPEND);
   ByteBuffer bb = ByteBuffer.wrap("12345".getBytes());
   s.truncate(0); // clear file
   s.position(0); // start position
   s.write(bb);
   bb.position(2);
   s.write(bb);
   //
   s.position(0);
   byte[] bbrb = new byte[(int) s.size()];
   s.read(ByteBuffer.wrap(bbrb));
   System.out.println(new String(bbrb)); // should be 12345345
   s.close();
 }
 private void executeWrite() throws IOException {
   System.out.println("executeWrite started.");
   try (SeekableByteChannel channel =
       Files.newByteChannel(
           Paths.get("c:/temp/channelExample.txt"),
           EnumSet.of(
               StandardOpenOption.CREATE,
               StandardOpenOption.WRITE,
               StandardOpenOption.TRUNCATE_EXISTING))) {
     String data =
         "This is a sample data ========================================"
             + "This is a sample data ========================================"
             + "This is a sample data ========================================"
             + "This is a sample data ========================================"
             + "This is a sample data ========================================\r\n";
     byte[] byteData = data.getBytes();
     ByteBuffer buf = ByteBuffer.allocate(10);
     int offset = 0;
     int length = buf.capacity();
     // read every 10 bytes and put the data into buffer and write it.
     while (true) {
       buf.clear(); // clear buffer to starting use.
       if ((offset + length) >= byteData.length) {
         length = byteData.length - offset;
       }
       buf.put(byteData, offset, length);
       buf.flip(); // you should call this method to read data from buffer.
       System.out.print(Charset.defaultCharset().decode(buf));
       buf
           .rewind(); // rewind the position because the above line used this buffer so position is
                      // at the end of data.
       channel.write(buf);
       offset += length;
       if (offset >= byteData.length) break;
     }
     System.out.println("writing data to channel finished");
   }
 }
Exemple #16
0
  /**
   * This will copy the template directory, renaming files named {@code foo.fixture} to {@code foo}
   * in the process. Files whose names end in {@code .expected} will not be copied.
   */
  @SuppressWarnings("PMD.EmptyCatchBlock")
  public ProjectWorkspace setUp() throws IOException {

    MoreFiles.copyRecursively(templatePath, destPath, BUILD_FILE_RENAME);

    // Stamp the buck-out directory if it exists and isn't stamped already
    try (OutputStream outputStream =
        new BufferedOutputStream(
            Channels.newOutputStream(
                Files.newByteChannel(
                    destPath.resolve(BuckConstant.getCurrentVersionFile()),
                    ImmutableSet.<OpenOption>of(
                        StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))))) {
      outputStream.write(BuckVersion.getVersion().getBytes(Charsets.UTF_8));
    } catch (FileAlreadyExistsException | NoSuchFileException e) {
      // If the current version file already exists we don't need to create it
      // If buck-out doesn't exist we don't need to stamp it
    }

    if (Platform.detect() == Platform.WINDOWS) {
      // Hack for symlinks on Windows.
      SimpleFileVisitor<Path> copyDirVisitor =
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs)
                throws IOException {
              // On Windows, symbolic links from git repository are checked out as normal files
              // containing a one-line path. In order to distinguish them, paths are read and
              // pointed
              // files are trued to locate. Once the pointed file is found, it will be copied to
              // target.
              // On NTFS length of path must be greater than 0 and less than 4096.
              if (attrs.size() > 0 && attrs.size() <= 4096) {
                String linkTo = new String(Files.readAllBytes(path), UTF_8);
                Path linkToFile;
                try {
                  linkToFile = templatePath.resolve(linkTo);
                } catch (InvalidPathException e) {
                  // Let's assume we were reading a normal text file, and not something meant to be
                  // a
                  // link.
                  return FileVisitResult.CONTINUE;
                }
                if (Files.isRegularFile(linkToFile)) {
                  Files.copy(linkToFile, path, StandardCopyOption.REPLACE_EXISTING);
                } else if (Files.isDirectory(linkToFile)) {
                  Files.delete(path);
                  MoreFiles.copyRecursively(linkToFile, path);
                }
              }
              return FileVisitResult.CONTINUE;
            }
          };
      Files.walkFileTree(destPath, copyDirVisitor);
    }

    // Disable the directory cache by default.  Tests that want to enable it can call
    // `enableDirCache` on this object.  Only do this if a .buckconfig.local file does not already
    // exist, however (we assume the test knows what it is doing at that point).
    if (!Files.exists(getPath(".buckconfig.local"))) {
      writeContentsToPath("[cache]\n  mode =", ".buckconfig.local");
    }

    isSetUp = true;
    return this;
  }
Exemple #17
0
  /**
   * This will copy the template directory, renaming files named {@code foo.fixture} to {@code foo}
   * in the process. Files whose names end in {@code .expected} will not be copied.
   */
  @SuppressWarnings("PMD.EmptyCatchBlock")
  public ProjectWorkspace setUp() throws IOException {

    MoreFiles.copyRecursively(templatePath, destPath, BUILD_FILE_RENAME);

    // Stamp the buck-out directory if it exists and isn't stamped already
    try (OutputStream outputStream =
        new BufferedOutputStream(
            Channels.newOutputStream(
                Files.newByteChannel(
                    destPath.resolve(BuckConstant.CURRENT_VERSION_FILE),
                    ImmutableSet.<OpenOption>of(
                        StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))))) {
      outputStream.write(BuckVersion.getVersion().getBytes(Charsets.UTF_8));
    } catch (FileAlreadyExistsException | NoSuchFileException e) {
      // If the current version file already exists we don't need to create it
      // If buck-out doesn't exist we don't need to stamp it
    }

    // If there's a local.properties in the host project but not in the destination, make a copy.
    Path localProperties = FileSystems.getDefault().getPath("local.properties");
    Path destLocalProperties = destPath.resolve(localProperties.getFileName());

    if (localProperties.toFile().exists() && !destLocalProperties.toFile().exists()) {
      Files.copy(localProperties, destLocalProperties);
    }

    if (Platform.detect() == Platform.WINDOWS) {
      // Hack for symlinks on Windows.
      SimpleFileVisitor<Path> copyDirVisitor =
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs)
                throws IOException {
              // On Windows, symbolic links from git repository are checked out as normal files
              // containing a one-line path. In order to distinguish them, paths are read and
              // pointed
              // files are trued to locate. Once the pointed file is found, it will be copied to
              // target.
              // On NTFS length of path must be greater than 0 and less than 4096.
              if (attrs.size() > 0 && attrs.size() <= 4096) {
                String linkTo = new String(Files.readAllBytes(path), UTF_8);
                Path linkToFile = null;
                try {
                  linkToFile = templatePath.resolve(linkTo);
                } catch (InvalidPathException e) {
                  // Let's assume we were reading a normal text file, and not something meant to be
                  // a
                  // link.
                  return FileVisitResult.CONTINUE;
                }
                if (Files.isRegularFile(linkToFile)) {
                  Files.copy(linkToFile, path, StandardCopyOption.REPLACE_EXISTING);
                } else if (Files.isDirectory(linkToFile)) {
                  Files.delete(path);
                  MoreFiles.copyRecursively(linkToFile, path);
                }
              }
              return FileVisitResult.CONTINUE;
            }
          };
      Files.walkFileTree(destPath, copyDirVisitor);
    }
    isSetUp = true;
    return this;
  }
  private static void processArchive(
      final Path path, final Set<Archive> output, final SettingsModelFactory settingsFactory)
      throws IOException, StarDBException {

    Archive originalArchive = new Archive(path);

    if (!originalArchive.extract()) {
      throw new IOException("Could not extract archive.");
    }

    Set<ArchiveFile> usedPaks = new HashSet<>();

    for (ArchiveFile file : originalArchive.getFiles()) {

      if (FileHelper.getExtension(file.getPath()).equals("modinfo")) {

        JsonObject o = JsonObject.readFrom(new String(file.getData()));

        String preformattedPath = o.get("path").asString().replaceAll("\"", "");

        if (preformattedPath.startsWith("./")) {
          preformattedPath = preformattedPath.replace("./", "");
        }

        if (preformattedPath.startsWith(".")) {
          preformattedPath = preformattedPath.replace(".", "");
        }

        if (preformattedPath.startsWith("/")) {
          preformattedPath = preformattedPath.replace("/", "");
        }

        Path modinfoPath = file.getPath();

        if (modinfoPath.getNameCount() > 2) {
          modinfoPath = modinfoPath.subpath(0, modinfoPath.getNameCount() - 1);
        } else if (modinfoPath.getNameCount() > 1) {
          modinfoPath = modinfoPath.getName(0);
        } else {
          modinfoPath = Paths.get("");
        }

        Archive outputArchive =
            new Archive(
                settingsFactory
                    .getInstance()
                    .getPropertyPath("modsdir")
                    .resolve(Paths.get(o.get("name").asString() + ".zip")));

        if (file.getPath().getNameCount() == 1) {
          outputArchive.addFile(new ArchiveFile(file.getData(), file.getPath(), false));
          log.debug(
              "'{}' -> '{}' relativized to '{}'", modinfoPath, file.getPath(), file.getPath());
        } else {
          outputArchive.addFile(
              new ArchiveFile(
                  file.getData(), modinfoPath.relativize(file.getPath()).normalize(), false));
          log.debug(
              "'{}' -> '{}' relativized to '{}'",
              modinfoPath,
              file.getPath(),
              modinfoPath.relativize(file.getPath()).normalize());
        }

        Path assetsPath = modinfoPath.resolve(Paths.get(preformattedPath));

        log.debug("Assets path for modinfo '{}': {}", file.getPath(), assetsPath);

        if (originalArchive.getFile(assetsPath) != null
            && !assetsPath.toString().isEmpty()
            && !originalArchive.getFile(assetsPath).isFolder()) {

          if (FileHelper.identifyType(originalArchive.getFile(assetsPath).getData())
              .equals("pak")) {

            log.debug("Assets for mod '{}' identified as .pak file: {}", modinfoPath, assetsPath);

            usedPaks.add(originalArchive.getFile(assetsPath));

            ArchiveFile modinfo = outputArchive.getFile(".modinfo");
            JsonObject o2 = JsonObject.readFrom(new String(modinfo.getData()));
            o2.set("path", "assets");

            modinfo.setData(o2.toString().getBytes());

            // TODO Update StarDB to let me pass in a byte array instead of needing to open a file

            Path tempPath = Paths.get("tempPak" + System.nanoTime());

            SeekableByteChannel tempPakFile =
                Files.newByteChannel(tempPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
            tempPakFile.write(ByteBuffer.wrap(originalArchive.getFile(assetsPath).getData()));
            tempPakFile.close();

            AssetDatabase database = AssetDatabase.open(tempPath);

            for (String assetFile : database.getFileList()) {
              outputArchive.addFile(
                  new ArchiveFile(
                      database.getAsset(assetFile), Paths.get("assets/" + assetFile), false));
              log.trace("Asset extracted: {} | {}", assetFile, Paths.get("assets/" + assetFile));
            }

            Files.deleteIfExists(tempPath);
          }

        } else {

          ArchiveFile modinfo = outputArchive.getFile(".modinfo");
          JsonObject o2 = JsonObject.readFrom(new String(modinfo.getData()));
          o2.set("path", "assets");

          modinfo.setData(o2.toString().getBytes());

          log.debug("Assets for mod '{}' is a standard assets folder: {}", modinfoPath, assetsPath);

          for (ArchiveFile f2 : originalArchive.getFiles()) {

            if ((assetsPath.toString().isEmpty() || f2.getPath().startsWith(assetsPath))
                && !f2.isFolder()
                && !f2.getPath().toString().endsWith(".modinfo")) {

              if (modinfoPath.toString().isEmpty()) {

                if (f2.getPath().getNameCount() == 1) {

                  if (!f2.getPath().startsWith(assetsPath)) {
                    outputArchive.addFile(
                        new ArchiveFile(
                            f2.getData(),
                            Paths.get("assets/").resolve(f2.getPath()).normalize(),
                            false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        Paths.get("assets/").resolve(f2.getPath()).normalize());
                  } else {
                    outputArchive.addFile(new ArchiveFile(f2.getData(), f2.getPath(), false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        f2.getPath());
                  }

                } else {

                  if (!f2.getPath().startsWith(assetsPath)) {
                    outputArchive.addFile(
                        new ArchiveFile(
                            f2.getData(),
                            Paths.get("assets/").resolve(f2.getPath()).normalize(),
                            false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        Paths.get("assets/").resolve(f2.getPath()).normalize());
                  } else {
                    outputArchive.addFile(new ArchiveFile(f2.getData(), f2.getPath(), false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        f2.getPath());
                  }
                }

              } else {

                if (f2.getPath().getNameCount() == 1) {

                  if (!modinfoPath.relativize(f2.getPath()).startsWith("assets")) {
                    outputArchive.addFile(
                        new ArchiveFile(
                            f2.getData(), Paths.get("assets/").resolve(f2.getPath()), false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        Paths.get("assets/").resolve(f2.getPath()));
                  } else {
                    outputArchive.addFile(new ArchiveFile(f2.getData(), f2.getPath(), false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        f2.getPath());
                  }

                } else {

                  if (!modinfoPath.relativize(f2.getPath()).startsWith("assets")) {
                    outputArchive.addFile(
                        new ArchiveFile(
                            f2.getData(),
                            Paths.get("assets/")
                                .resolve(modinfoPath.relativize(f2.getPath()).normalize()),
                            false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        Paths.get("assets/")
                            .resolve(modinfoPath.relativize(f2.getPath()).normalize()));
                  } else {
                    outputArchive.addFile(
                        new ArchiveFile(
                            f2.getData(), modinfoPath.relativize(f2.getPath()).normalize(), false));
                    log.trace(
                        "'{}' -> '{}' relativized to '{}'",
                        modinfoPath,
                        f2.getPath(),
                        modinfoPath.relativize(f2.getPath()).normalize());
                  }
                }
              }
            }
          }
        }

        outputArchive.writeToFile(
            settingsFactory
                .getInstance()
                .getPropertyPath("modsdir")
                .resolve(Paths.get(o.get("name").asString() + ".zip"))
                .toFile()); // TODO

        output.add(outputArchive);
      }
    }

    for (ArchiveFile file : originalArchive.getFiles()) {

      if (!usedPaks.contains(file)
          && !file.isFolder()
          && FileHelper.identifyType(file.getData()).equals("pak")) {

        log.debug("Additional .pak identified: {}", file.getPath());

        Path tempPath = Paths.get("tempPak" + System.nanoTime());

        SeekableByteChannel tempPakFile =
            Files.newByteChannel(tempPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
        tempPakFile.write(ByteBuffer.wrap(file.getData()));
        tempPakFile.close();

        AssetDatabase database = AssetDatabase.open(tempPath);
        log.debug(database.getFileList());

        if (database.getAsset("/pak.modinfo") != null) {
          log.debug("{} has a .modinfo file, parsing into mod.", file.getPath());
          processPakFile(tempPath, output, settingsFactory);
        } else {
          log.debug("{} does not contain a .modinfo file, skipping.", file.getPath());
        }

        Files.deleteIfExists(tempPath);
      }
    }
  }