예제 #1
0
  private static void append(
      File file,
      FileFilter filter,
      int baseNameLen,
      String addedTopFolder,
      TarArchiveOutputStream tarOut)
      throws IOException {

    String name = file.getAbsolutePath();
    if (name.length() <= baseNameLen) name = "";
    else name = name.substring(baseNameLen);
    if (File.separatorChar == '\\') name = name.replace('\\', '/');
    if (addedTopFolder != null) name = addedTopFolder + '/' + name;

    if (FileUtils.isSymlink(file)) {
      String linkTarget = FileUtils.readSymbolicLink(file);
      if (linkTarget != null) {
        TarArchiveEntry entry = new TarArchiveEntry(name, TarConstants.LF_SYMLINK);
        entry.setName(name);
        entry.setLinkName(linkTarget);
        tarOut.putArchiveEntry(entry);
      }
      return;
    }

    ArchiveEntry entry = tarOut.createArchiveEntry(file, name);
    tarOut.putArchiveEntry(entry);
    File[] children = file.listFiles(filter);
    if (children != null) {
      tarOut.closeArchiveEntry();
      // This is a directory. Append its children
      for (File child : children) append(child, filter, baseNameLen, addedTopFolder, tarOut);
      return;
    }

    // Append the content of the file
    InputStream input = new FileInputStream(file);
    try {
      StreamUtil.copy(input, tarOut);
      tarOut.closeArchiveEntry();
    } finally {
      StreamUtil.close(input);
    }
  }
예제 #2
0
  public static void pack(
      File sourceFolder,
      OutputStream output,
      FileFilter filter,
      boolean includeTopFolder,
      String addedTopFolder)
      throws IOException {
    TarArchiveOutputStream tarOut = new TarArchiveOutputStream(output);
    tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
    String absName = sourceFolder.getAbsolutePath();
    int baseNameLen = absName.length() + 1;
    if (includeTopFolder) baseNameLen -= (sourceFolder.getName().length() + 1);

    try {
      append(sourceFolder, filter, baseNameLen, addedTopFolder, tarOut);
    } finally {
      StreamUtil.close(tarOut);
    }
  }
예제 #3
0
  /**
   * Unpack the content read from <i>source</i> into <i>targetFolder</i>. If the
   * <i>skipTopFolder</i> is set, then don't assume that the archive contains one single folder and
   * unpack the content of that folder, not including the folder itself.
   *
   * @param source The input source. Must be in <i>TAR</i> format.
   * @param targetFolder The destination folder for the unpack. Not used when a <tt>fileCatcher</tt>
   *     is provided
   * @param skipTopFolder Set to <code>true</code> to unpack beneath the top folder of the archive.
   *     The archive must consist of one single folder and nothing else in order for this to work.
   * @param fileCatcher Used when specific files should be picked from the archive without writing
   *     them to disk. Can be <tt>null</tt>.
   * @throws IOException
   */
  public static void unpack(
      InputStream source, File targetFolder, boolean skipTopFolder, FileCatcher fileCatcher)
      throws IOException {
    String topFolderName = null;
    Map<File, Map<Integer, List<String>>> chmodMap =
        new HashMap<File, Map<Integer, List<String>>>();
    TarArchiveInputStream in = new TarArchiveInputStream(source);
    try {
      TarArchiveEntry te = in.getNextTarEntry();
      if (te == null) {
        throw new IOException("No entry in the tar file");
      }
      do {
        if (te.isGlobalPaxHeader()) continue;

        String name = te.getName();
        if (name.startsWith("./._"))
          // MacOS specific extended attributes addition. Just skip it
          continue;

        if (skipTopFolder) {
          int firstSlash = name.indexOf('/');
          if (firstSlash < 0) throw new IOException("Archive doesn't contain one single folder");

          String tfName = name.substring(0, firstSlash);
          if (topFolderName == null) topFolderName = tfName;
          else if (!tfName.equals(topFolderName))
            throw new IOException("Archive doesn't contain one single folder");
          name = name.substring(firstSlash + 1);
        }
        if (name.length() == 0) continue;

        String linkName = te.getLinkName();
        if (linkName != null) {
          if (linkName.trim().equals("")) linkName = null;
        }

        if (fileCatcher != null) {
          if (linkName == null && !te.isDirectory() && fileCatcher.accept(name)) {
            if (fileCatcher.catchData(name, in))
              // We're done here
              return;
          }
          continue;
        }

        File outFile = new File(targetFolder, name);
        if (linkName != null) {
          if (!OsUtil.link(targetFolder, name, te.getLinkName()))
            throw new IOException(
                "Archive contains links but they are not supported on this platform");
        } else {
          if (te.isDirectory()) {
            outFile.mkdirs();
          } else {
            outFile.getParentFile().mkdirs();
            OutputStream target = new FileOutputStream(outFile);
            StreamUtil.copy(in, target);
            target.close();
            outFile.setLastModified(te.getModTime().getTime());
          }
          registerChmodFile(chmodMap, targetFolder, Integer.valueOf(te.getMode()), name);
        }
      } while ((te = in.getNextTarEntry()) != null);
    } finally {
      StreamUtil.close(in);
    }
    chmod(chmodMap);
  }