java.lang.Object
net.i2p.util.FileUtil

public class FileUtilextends Object
General helper methods for messing with files

These are static methods that do NOT convert arguments to absolute paths for a particular context and directory.

Callers should ALWAYS provide absolute paths as arguments, and should NEVER assume files are in the current working directory.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static Class<?>
    The unpacker implementation class, resolved once by findPack200Class().
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    copy(File src, File dst, boolean overwriteExisting, boolean quiet)
    Copy the file, optionally overwriting the destination, optionally logging failures.
    static boolean
    copy(String source, String dest, boolean overwriteExisting)
    Copy the file, optionally overwriting the destination.
    static boolean
    copy(String source, String dest, boolean overwriteExisting, boolean quiet)
    Copy the file, optionally overwriting the destination, optionally logging failures.
    static boolean
    extractZip(File zipfile, File targetDir)
    Extract every entry of the zip archive into targetDir, creating missing parent directories as needed.
    static boolean
    extractZip(File zipfile, File targetDir, int logLevel)
    Warning - do not call any new classes from here, or update will crash the JVM.
    private static Class<?>
    Locate a Pack200 unpacker.
    static boolean
    Public since 0.8.3.
    static void
    main(String[] args)
    Usage: FileUtil (delete path | copy source dest | rename from to | unzip path.zip).
    static void
    readFile(String path, String root, OutputStream out)
    Dump the contents of the given path (relative to the root) to the output stream.
    static String
    readTextFile(String filename, int maxNumLines, boolean startAtBeginning)
    Read in the last few lines of a (newline delimited) textfile, or null if the file doesn't exist.
    static boolean
    rename(File from, File to)
    Try to rename, if it doesn't work then copy and delete the old.
    static final boolean
    rmdir(File target, boolean failIfNotEmpty)
    Delete the path as well as any files or directories underneath it.
    static final boolean
    rmdir(String path, boolean failIfNotEmpty)
    Delete the path as well as any files or directories underneath it.
    private static void
    Unpack a .pack stream with the io.pack200 fork, discovered at runtime so the jar is not required at compile time.
    static boolean
    verifyZip(File zipfile)
    Verify the integrity of a zipfile.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • P200

      private static volatile Class<?> P200
      The unpacker implementation class, resolved once by findPack200Class().

      Set to null permanently when no unpacker is on the classpath, so we do not retry the (failing) class lookup on every .pack entry in an update zip.

  • Constructor Details

    • FileUtil

      public FileUtil()
      Constructor. Every operation here is a static function of the paths passed to it, so an instance carries no state.
  • Method Details

    • rmdir

      public static final boolean rmdir(String path, boolean failIfNotEmpty)
      Delete the path as well as any files or directories underneath it.
      Parameters:
      path - path to the directory being deleted
      failIfNotEmpty - if true, do not delete anything if the directory is not empty (and return false)
      Returns:
      true if the path no longer exists (aka was removed), false if it remains
    • rmdir

      public static final boolean rmdir(File target, boolean failIfNotEmpty)
      Delete the path as well as any files or directories underneath it.
      Parameters:
      target - the file or directory being deleted
      failIfNotEmpty - if true, do not delete anything if the directory is not empty (and return false)
      Returns:
      true if the path no longer exists (aka was removed), false if it remains
    • extractZip

      public static boolean extractZip(File zipfile, File targetDir)
      Extract every entry of the zip archive into targetDir, creating missing parent directories as needed.

      Since 0.7.12, any files inside the zip that have a .jar.pack or .war.pack suffix are transparently unpacked to a .jar or .war file using unpack200. Logs at WARN level to wrapper.log.

      Parameters:
      zipfile - the zip archive to extract
      targetDir - the directory the entries are written under, with any missing parent directories created as needed
      Returns:
      true if every entry was extracted, false if any entry was refused or could not be read or written
    • extractZip

      public static boolean extractZip(File zipfile, File targetDir, int logLevel)
      Warning - do not call any new classes from here, or update will crash the JVM.
      Parameters:
      zipfile - the zip archive to extract
      targetDir - the directory the entries are written under, with any missing parent directories created as needed
      logLevel - severity threshold for extraction progress messages; messages at or below this level are printed
      Returns:
      true if it was copied successfully
    • verifyZip

      public static boolean verifyZip(File zipfile)
      Verify the integrity of a zipfile. There doesn't seem to be any library function to do this, so we basically go through all the motions of extractZip(File, File) above, unzipping everything but throwing away the data.

      Todo: verify zip header? Although this would break the undocumented practice of renaming the i2pupdate.sud file to i2pupdate.zip and letting the unzip method skip over the leading 56 bytes of "junk" (sig and version).

      Parameters:
      zipfile - the zip archive to check, whose entries are decompressed and discarded rather than written out
      Returns:
      true if ok
    • isPack200Supported

      public static boolean isPack200Supported()
      Public since 0.8.3.
      Returns:
      whether pack200 supported
    • findPack200Class

      private static Class<?> findPack200Class()
      Locate a Pack200 unpacker.

      The JDK's own java.util.jar.Pack200 was removed in Java 14, so on every Java we support the only implementation is the io.pack200 fork, shipped as lib/pack200.jar in the update payload itself. Loading it reflectively keeps it off the compile classpath, so the router still starts without it.

      Returns:
      the Pack200 class, or null if unavailable
    • unpack

      private static void unpack(InputStream in, JarOutputStream out) throws Exception
      Unpack a .pack stream with the io.pack200 fork, discovered at runtime so the jar is not required at compile time.

      Caller must close streams.

      Parameters:
      in - the .pack format input stream to read from
      out - the jar output stream the unpacked entries are written to
      Throws:
      IOException - on unpack error or if the library is unavailable. Will not throw ClassNotFoundException.
      InvocationTargetException - on duplicate zip entries in the packed jar
      Exception
    • readTextFile

      public static String readTextFile(String filename, int maxNumLines, boolean startAtBeginning)
      Read in the last few lines of a (newline delimited) textfile, or null if the file doesn't exist.

      Warning - this inefficiently allocates a StringBuilder of size maxNumLines*80, so don't make it too big. Warning - converts \r\n to \n Warning - inefficient if startAtBeginning is false, see console LogsHelper for better version.

      Parameters:
      filename - the path of the newline-delimited text file to read
      maxNumLines - max number of lines (or -1 for unlimited)
      startAtBeginning - if true, read the first maxNumLines, otherwise read the last maxNumLines
      Returns:
      string or null; does not throw IOException.
    • readFile

      public static void readFile(String path, String root, OutputStream out) throws IOException
      Dump the contents of the given path (relative to the root) to the output stream. The path must not go above the root, either - if it does, it will throw a FileNotFoundException

      Closes the OutputStream out on successful completion but leaves it open when throwing IOE.

      Parameters:
      path - the file to dump, relative to the root, which may not escape the root directory
      root - the directory that path is resolved against
      out - the stream the file is copied to; closed on successful completion but left open when an IOException is thrown
      Throws:
      FileNotFoundException - if path is empty, does not exist, or resolves outside the root directory
      IOException
    • copy

      public static boolean copy(String source, String dest, boolean overwriteExisting)
      Copy the file, optionally overwriting the destination.
      Parameters:
      source - the path of the file to copy
      dest - the path of the copy to create
      overwriteExisting - if true, replace dest when it already exists
      Returns:
      true if it was copied successfully
    • copy

      public static boolean copy(String source, String dest, boolean overwriteExisting, boolean quiet)
      Copy the file, optionally overwriting the destination, optionally logging failures.
      Parameters:
      source - the path of the file to copy
      dest - the path of the copy to create
      overwriteExisting - if true, replace dest when it already exists
      quiet - don't log fails to wrapper log if true
      Returns:
      true if it was copied successfully
    • copy

      public static boolean copy(File src, File dst, boolean overwriteExisting, boolean quiet)
      Copy the file, optionally overwriting the destination, optionally logging failures.
      Parameters:
      src - the existing file to copy
      dst - the destination, which is treated as a directory when one already exists at that path
      overwriteExisting - if true, replace dst when it already exists
      quiet - don't log fails to wrapper log if true
      Returns:
      true if it was copied successfully
    • rename

      public static boolean rename(File from, File to)
      Try to rename, if it doesn't work then copy and delete the old. Always overwrites any existing "to" file. Method moved from SingleFileNamingService.
      Parameters:
      from - the existing file to rename or move
      to - the destination path, which is replaced if it already exists
      Returns:
      true if it was renamed / copied successfully
    • main

      public static void main(String[] args)
      Usage: FileUtil (delete path | copy source dest | rename from to | unzip path.zip).
      Parameters:
      args - the subcommand and its operands: delete path | copy source dest | rename from to | unzip path.zip