Class MoreFiles

java.lang.Object
com.atlassian.bitbucket.util.MoreFiles

public class MoreFiles extends Object
Additional utility methods missing from Files.
Since:
5.11
  • Method Details

    • canOpen

      public static boolean canOpen(@Nonnull Path path)
      An NFS-safe version of Files.exists(Path, LinkOption...)} which actually opens the file to verify its existence.

      NFS can cache file stat information, which can lead to Files.exists(Path, LinkOption...)} returning true for files that no longer exist when files are deleted on other nodes. The only way to ensure the file really exists is to open it, which won't be fooled by cached stat information.

      Parameters:
      path - the path to the file to test
      Returns:
      true if the file can be opened; otherwise, false if not
      Since:
      7.16
    • cleanDirectory

      public static void cleanDirectory(@Nonnull Path directory) throws IOException
      Deletes any files or subdirectories in the specified directory and leaves the directory empty.
      Parameters:
      directory - the directory to clean
      Throws:
      IOException - if the path does not denote a directory, or the directory's contents could not be deleted
    • deleteOnExit

      public static void deleteOnExit(@Nonnull Path path)
      Registers the provided path to be deleted when the JVM exits.

      Delete-on-exit is performed on a best-effort basis, and should not be relied upon as the primary solution for deleting files. Additionally, it only works for files and empty directories.

      Parameters:
      path - the path to register for deletion when the JVM exits
      See Also:
    • deleteQuietly

      public static boolean deleteQuietly(@Nonnull Path path)
      Recursively deletes the specified path, suppressing any IOExceptions that are thrown.
      Parameters:
      path - the path to delete, which may be a file or a directory
      Returns:
      true if the path was deleted; otherwise, false if it did not exist or could not be deleted
    • deleteRecursively

      public static void deleteRecursively(@Nonnull Path path) throws IOException
      Recursively deletes the specified path.

      If the specified Path denotes a directory, the directory's contents are recursively deleted, depth-first, to empty the directory so it can be deleted. If any files or subdirectories can't be deleted, an exception will be thrown. Note that some files and subdirectories may have been deleted prior to the exception being thrown. Additionally, if the directory contains any symbolic links the links themselves are deleted, not their targets.

      If the specified Path denotes a symbolic link, the symbolic link itself is deleted, rather than the target of the link. If the path is a symbolic link to a directory, that directory's contents are not removed.

      If the specified Path denotes a file, it is deleted.

      If the specified path does not exist, nothing happens and no exception is thrown.

      Parameters:
      path - the path to delete, which may be a file or a directory
      Throws:
      IOException - if the specified path cannot be deleted
    • getLastModified

      public static long getLastModified(@Nonnull Path path)
      Gets the last modified time for the specified Path, in milliseconds.

      Like File.lastModified(), if the path does not exist or its attributes cannot be read, 0L is returned rather than throwing an exception. Use Files.getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...) directly if an exception is desired.

      Parameters:
      path - the path to retrieve the last modified time for
      Returns:
      the file's last modified time, in milliseconds, or 0L if the time could not be determined
    • isAclSupported

      public static boolean isAclSupported(@Nonnull Path path) throws IOException
      Gets the file store for the specified Path, and returns whether the file store supports ACLs. NTFS on Windows supports ACLs, but most Linux filesystems, and APFS and HFS+ on macOS, do not; they use POSIX instead.
      Parameters:
      path - the path to check, which is used to find the appropriate file store
      Returns:
      true if the path's file store supports ACLs; otherwise, false
      Throws:
      IOException - if the file store cannot be determined for the specified path
      Since:
      6.2
    • isPosixSupported

      public static boolean isPosixSupported(@Nonnull Path path) throws IOException
      Gets the file store for the specified Path, and returns whether the file store supports POSIX. Most Linux filesystems support POSIX, as do APFS and HFS+ on macOS, but, for example, NTFS on Windows does not; it uses ACLs instead.
      Parameters:
      path - the path to check, which is used to find the appropriate file store
      Returns:
      true if the path's file store supports POSIX; otherwise, false
      Throws:
      IOException - if the file store cannot be determined for the specified path
      Since:
      6.2
    • isWithin

      public static boolean isWithin(@Nonnull Path path, @Nonnull Path expectedParent) throws IOException
      Returns true if the specified path is contained within the expectedParent. This should be used to ensure paths created with user-entered data don't "escape" the specified parent, to prevent path traversal attacks.
      Parameters:
      path - the path to validate
      expectedParent - the required parent directory
      Returns:
      true if path is contained within expectedParent; otherwise, false
      Throws:
      IllegalArgumentException - if expectedParent does not exist or is not a directory
      IOException - if the real path for either of the provided paths cannot be resolved
    • mkdir

      @Nonnull public static Path mkdir(@Nonnull Path directory)
      Creates the specified directory, if it does not already exist. If the path does exist, it is validated that it is a directory and not a file.
      Parameters:
      directory - the directory to create
      Returns:
      the created directory
      Throws:
      IllegalStateException - if the directory path already exists and is not a directory, or if the directory cannot be created
      NullPointerException - if the provided directory is null
    • mkdir

      @Nonnull public static Path mkdir(@Nonnull Path parent, @Nonnull String child)
      Creates the specified child directory beneath the parent, if it does not already exist. If the path does exist, it is validated that it is a directory and not a file.
      Parameters:
      parent - the base path for creating the new directory
      child - the path beneath the parent for the new directory
      Returns:
      the created directory
      Throws:
      IllegalArgumentException - if the child path is blank or empty
      IllegalStateException - if the child path already exists and is not a directory, or if the directory cannot be created
      NullPointerException - if the provided parent or child is null
    • pathSafe

      @Nonnull public static String pathSafe(@Nonnull String value)
      Creates a path-safe version of a string, replacing all potentially unsafe characters with a - character.
      Parameters:
      value - the value to transform into a path safe string
      Returns:
      the path safe string
      Since:
      7.16
    • requireWithin

      public static void requireWithin(@Nonnull Path path, @Nonnull Path expectedParent) throws IOException
      Validates that the specified path is contained within the expectedParent. This should be used to ensure paths created with user-entered data don't "escape" the specified parent, to prevent path traversal attacks.
      Parameters:
      path - the path to validate
      expectedParent - the required parent directory
      Throws:
      IllegalArgumentException - if expectedParent does not exist or is not a directory, or if path is not contained within it
      IOException - if the real path for either of the provided paths cannot be resolved
    • resolve

      @Nonnull public static Path resolve(@Nonnull Path path, @Nonnull String first, @Nonnull String... more)
      Simplifies resolving several subpaths in a single call.
      Parameters:
      path - the base path, from which subpaths should be resolved
      first - the first subpath, used to enforce that at least a single subpath is provided
      more - zero or more additional subpaths
      Returns:
      the resolved path
    • setPermissions

      public static void setPermissions(@Nonnull SetFilePermissionRequest request) throws IOException
      Sets the file permissions according to the specifications provided in the request. For Unix systems this will map the provided permissions to the corresponding PosixFilePermission. For Windows systems ACL entries will be put together as follows:
      • Owner permissions: These will be applied to the owner principal. Also, for convenience, they will be applied to the Administrator group (if it exists) since its members can override ACLs anyway
      • World permissions: These will be applied to the Everyone group.
      • Group permissions: These will be ignored. In POSIX-compliant OSes files and directories are associated with both a user and a group and the permission model explicitly provides for setting a group permission agnostic of the group's name. The ACL model used by Windows requires knowing the name of the group you want to provision.
      Parameters:
      request - describes the file permissions to set
      Throws:
      IllegalArgumentException - if the provided path does not exist, or exists and is not a regular file
      IOException - if the real path for either of the provided paths cannot be resolved
    • size

      public static long size(@Nonnull Path path)
      Gets the size of the specified Path.

      Like File.length(), if the path does not exist or its attributes cannot be read, 0L is returned rather than throwing an exception. Use Files.size(java.nio.file.Path) directly if an exception is desired.

      Parameters:
      path - the path to retrieve the size of
      Returns:
      the file's size, or 0L if the size could not be determined
    • totalSize

      public static long totalSize(@Nonnull Path path)
      Calculates the total size of the specified path.

      If the specified Path denotes a directory, its contents are recursively traversed to compute its overall size. For directories containing a large number of files this can be quite slow, so it should be used with caution.

      If the specified Path denotes a symbolic link, its size (generally the length of its target path) is reported. Symbolic links are not followed.

      If the specified Path denotes a file, its size is reported.

      Parameters:
      path - the path to calculate a size for
      Returns:
      the calculated size, or 0L if the size could not be calculated
    • touch

      public static void touch(@Nonnull Path path) throws IOException
      Creates the specified path, if it doesn't exist, or sets its last modified time if it does.
      Parameters:
      path - the path to create or set a last modification time for
      Throws:
      IOException - if a nonexistent file cannot be created, or if the last modification time cannot be set for an existing file
    • toString

      @Nonnull public static String toString(@Nonnull Path path) throws IOException
      Reads the entire contents of the specified path using the UTF-8 character set.

      Callers should exercise caution when using this method, as it may result in reading a significant amount of data into memory. Where possible, callers are encouraged to stream file contents instead.

      Parameters:
      path - the path to read
      Returns:
      the file's contents
      Throws:
      IOException - if the file cannot be read
    • toString

      @Nonnull public static String toString(@Nonnull Path path, @Nonnull Charset charset) throws IOException
      Reads the entire contents of the specified path using the provided character set.

      Callers should exercise caution when using this method, as it may result in reading a significant amount of data into memory. Where possible, callers are encouraged to stream file contents instead.

      Parameters:
      path - the path to read
      charset - the character set to use to decode the file's contents
      Returns:
      the file's contents
      Throws:
      IOException - if the file cannot be read
    • write

      @Nonnull public static Path write(@Nonnull Path path, @Nonnull String value, @Nonnull OpenOption... options) throws IOException
      Writes the provided value to the specified path using the UTF-8 character set.
      Parameters:
      path - the path to write
      value - the value to write
      options - OpenOptions to control how the path is accessed
      Returns:
      the provided path
      Throws:
      IOException - if the file cannot be written
    • write

      @Nonnull public static Path write(@Nonnull Path path, @Nonnull String value, @Nonnull Charset charset, @Nonnull OpenOption... options) throws IOException
      Writes the provided value to the specified path using the provided character set.
      Parameters:
      path - the path to write
      value - the value to write
      charset - the character set to use to encode the value to bytes
      options - OpenOptions to control how the path is accessed
      Returns:
      the provided path
      Throws:
      IOException - if the file cannot be written