Package com.norconex.commons.lang.file

# Class FileUtil

java.lang.Object
com.norconex.commons.lang.file.FileUtil

public final class FileUtil extends Object
Utility methods when dealing with files and directories.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final File[]`
  `EMPTY_FILE_ARRAY`
  `static final Path[]`
  `EMPTY_PATH_ARRAY`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static File`
  `createDateDirs(File parentDir)`
  Creates (if not already existing) a series of directories reflecting the current date, up to the day unit, under a given parent directory.
  `static File`
  `createDateDirs(File parentDir, Date date)`
  Creates (if not already existing) a series of directories reflecting a date, up to the day unit, under a given parent directory.
  `static File`
  `createDateFormattedDirs(@NonNull File parentDir, @NonNull Date dateTime, String format)`
  Creates (if not already existing) a series of directories reflecting the specified date format (from `SimpleDateFormat`), under a given parent directory.
  `static File`
  `createDateTimeDirs(File parentDir)`
  Creates (if not already existing) a series of directories reflecting the current date and time, up to the seconds, under a given parent directory.
  `static File`
  `createDateTimeDirs(File parentDir, Date dateTime)`
  Creates (if not already existing) a series of directories reflecting a date and time, up to the seconds, under a given parent directory.
  `static File`
  `createDirsForFile(File file)`
  Create all parent directories for a file if they do not exists.
  `static File`
  `createURLDirs(@NonNull File parentDir, @NonNull String url, boolean truncate)`
  Creates (if not already existing) a series of directories matching URL segments, under a given parent directory.
  `static File`
  `createURLDirs(File parentDir, String url)`
  Creates (if not already existing) a series of directories matching URL segments, under a given parent directory.
  `static File`
  `createURLDirs(File parentDir, URL url)`
  Creates (if not already existing) a series of directories matching URL segments, under a given parent directory.
  `static File`
  `createURLDirs(File parentDir, URL url, boolean truncate)`
  Creates (if not already existing) a series of directories matching URL segments, under a given parent directory.
  `static void`
  `delete(File file)`
  Deletes a file or empty directory recursively, in a more robust way.
  `static int`
  `deleteEmptyDirs(File parentDir)`
  Recursively deletes all empty directories.
  `static int`
  `deleteEmptyDirs(File parentDir, Date date)`
  Recursively deletes all directories that are empty and are older than the given date.
  `static int`
  `deleteEmptyDirs(Path parentDir)`
  Recursively deletes all empty directories.
  `static int`
  `deleteEmptyDirs(Path parentDir, Date date)`
  Recursively deletes all directories that are empty and are older than the given date.
  `static boolean`
  `dirEmpty(File dir)`
  Gets whether a directory is empty of files or directories in an efficient way which does not load all files.
  `static boolean`
  `dirEmpty(Path dir)`
  Gets whether a directory is empty of files or directories in an efficient way which does not load all files.
  `static boolean`
  `dirHasFile(File dir, FileFilter filter)`
  Recursively gets whether a directory contains at least one file matching the given file filter.
  `static boolean`
  `dirHasFile(Path dir, FileFilter filter)`
  Recursively gets whether a directory contains at least one file matching the given file filter.
  `static String`
  `fromSafeFileName(String safeFileName)`
  Converts a "safe" file name originally created with `toSafeFileName(String)` into its original string.
  `static String[]`
  `head(File file, int numberOfLinesToRead)`
  Returns the specified number of lines starting from the beginning of a text file.
  `static String[]`
  `head(File file, String encoding, int numberOfLinesToRead)`
  Returns the specified number of lines starting from the beginning of a text file, using the given encoding.
  `static String[]`
  `head(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines)`
  Returns the specified number of lines starting from the beginning of a text file, using the given encoding.
  `static String[]`
  `head(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines, Predicate<String> filter)`
  Returns the specified number of lines starting from the beginning of a text file, using the given encoding.
  `static boolean`
  `isDirectory(File dir)`
  Null-safe alternative to `Files.isDirectory(Path, java.nio.file.LinkOption...)` A `null` directory always returns `false`.
  `static boolean`
  `isDirectory(Path dir)`
  Null-safe alternative to `Files.isDirectory(Path, java.nio.file.LinkOption...)` A `null` directory always returns `false`.
  `static boolean`
  `isFile(File file)`
  Null-safe alternative to `File.isFile()`.
  `static boolean`
  `isFile(Path file)`
  Null-safe alternative to `Files.isRegularFile(Path, java.nio.file.LinkOption...)`.
  `static void`
  `moveFile(@NonNull File sourceFile, @NonNull File targetFile)`
  Moves a file to a new file location.
  `static void`
  `moveFile(@NonNull Path sourceFile, @NonNull Path targetFile)`
  Moves a file to a new file location.
  `static File`
  `moveFileToDir(@NonNull File sourceFile, @NonNull File targetDir)`
  Moves a file to a directory.
  `static Path`
  `moveFileToDir(@NonNull Path sourceFile, @NonNull Path targetDir)`
  Moves a file to a directory.
  `static String[]`
  `tail(File file, int numberOfLinesToRead)`
  Returns the specified number of lines starting from the end of a text file.
  `static String[]`
  `tail(File file, String encoding, int numberOfLinesToRead)`
  Returns the specified number of lines starting from the end of a text file.
  `static String[]`
  `tail(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines)`
  Returns the specified number of lines starting from the end of a text file.
  `static String[]`
  `tail(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines, Predicate<String> filter)`
  Returns the specified number of lines starting from the end of a text file.
  `static File`
  `toDateFormattedDir(@NonNull File parentDir, @NonNull Date dateTime, String format)`
  Gets (but does not create) a series of directories reflecting the specified date format (from `SimpleDateFormat`), under a given parent directory.
  `static Path`
  `toPath(File file)`
  Null-safe alternative to `File.toPath()`.
  `static Path[]`
  `toPaths(File[] files)`
  Converts all supplied files to `Path` (`null` entries remain `null`).
  `static List<Path>`
  `toPaths(Collection<File> files)`
  Converts all supplied files to `Path` (`null` entries remain `null`).
  `static String`
  `toSafeFileName(String unsafeFileName)`
  Converts any String to a valid file-system file name representation.
  `static File`
  `toURLDir(@NonNull File parentDir, @NonNull String url, boolean truncate)`
  Gets (but does not create) a directory matching URL segments, under a given parent directory.
  `static File`
  `toURLDir(@NonNull File parentDir, @NonNull URL url, boolean truncate)`
  Gets (but does not create) a directory matching URL segments, under a given parent directory.
  `static File`
  `toURLDir(File parentDir, String url)`
  Gets (but does not create) a directory matching URL segments, under a given parent directory.
  `static File`
  `toURLDir(File parentDir, URL url)`
  Gets (but does not create) a directory matching URL segments, under a given parent directory.
  `static void`
  `visitAllDirs(File dir, FileVisitor visitor)`
  Visits only directories under a directory.
  `static void`
  `visitAllDirs(File dir, FileVisitor visitor, FileFilter filter)`
  Visits only directories under a directory.
  `static void`
  `visitAllDirsAndFiles(File dir, FileVisitor visitor)`
  Visits all files and directories under a directory.
  `static void`
  `visitAllDirsAndFiles(File dir, FileVisitor visitor, FileFilter filter)`
  Visits all files and directories under a directory.
  `static void`
  `visitAllFiles(File dir, FileVisitor visitor)`
  Visits all files (and only files) under a directory, including sub-directories.
  `static void`
  `visitAllFiles(File dir, FileVisitor visitor, FileFilter filter)`
  Visits all files (and only files) under a directory, including sub-directories.
  `static void`
  `visitEmptyDirs(File dir, FileVisitor visitor)`
  Visits only empty directories under a directory.
  `static void`
  `visitEmptyDirs(File dir, FileVisitor visitor, FileFilter filter)`
  Visits only empty directories under a directory.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### EMPTY_PATH_ARRAY

    public static final Path[] EMPTY_PATH_ARRAY
    Since:
      3.0.0

  - ### EMPTY_FILE_ARRAY

    public static final File[] EMPTY_FILE_ARRAY
    Since:
      3.0.0

- ## Method Details

  - ### dirEmpty

    public static boolean dirEmpty(File dir) throws IOException
    Gets whether a directory is empty of files or directories in an efficient way which does not load all files. The directory must exist and be a valid directory (e.g., not a file).
    Parameters:
      `dir` - the directory to check for emptiness
    Returns:
      `true` if directory exists and is empty
    Throws:
      `IOException` - if an I/O error occurs
    Since:
      2.0.0

  - ### dirEmpty

    public static boolean dirEmpty(Path dir) throws IOException
    Gets whether a directory is empty of files or directories in an efficient way which does not load all files. The directory must exist and be a valid directory (e.g., not a file).
    Parameters:
      `dir` - the directory to check for emptiness
    Returns:
      `true` if directory exists and is empty
    Throws:
      `IOException` - if an I/O error occurs
    Since:
      3.0.0

  - ### dirHasFile

    public static boolean dirHasFile(File dir, FileFilter filter) throws IOException
    Recursively gets whether a directory contains at least one file matching the given file filter.
    Parameters:
      `dir` - directory to inspect
      `filter` - file or directory filter
    Returns:
      `true` upon filter matching a file or directory
    Throws:
      `IOException` - if an I/O error occurs

  - ### dirHasFile

    public static boolean dirHasFile(Path dir, FileFilter filter) throws IOException
    Recursively gets whether a directory contains at least one file matching the given file filter.
    Parameters:
      `dir` - directory to inspect
      `filter` - file or directory filter
    Returns:
      `true` upon filter matching a file or directory
    Throws:
      `IOException` - if an I/O error occurs
    Since:
      3.0.0

  - ### toSafeFileName

    public static String toSafeFileName(String unsafeFileName)
    Converts any String to a valid file-system file name representation. The valid file name is constructed so it can be written to virtually any operating system. It will escape every characters that are not alphanumeric, hyphen, or dot. Use `fromSafeFileName(String)` to get back the original name.
    Parameters:
      `unsafeFileName` - the file name to make safe.
    Returns:
      valid file name

  - ### fromSafeFileName

    public static String fromSafeFileName(String safeFileName)
    Converts a "safe" file name originally created with `toSafeFileName(String)` into its original string.
    Parameters:
      `safeFileName` - the file name to convert to its original form
    Returns:
      original string

  - ### moveFileToDir

    public static File moveFileToDir(@NonNull @NonNull File sourceFile, @NonNull @NonNull File targetDir) throws IOException
    Moves a file to a directory. Like `moveFile(File, File)`:
    - If the target directory does not exists, it creates it first.
    - If the target file already exists, it deletes it first.
    - If target file deletion does not work, it will try 10 times, waiting half a second between each try to give a chance to whatever OS lock on the file to go.
    - It throws a IOException if the move failed (as opposed to fail silently).
    Parameters:
      `sourceFile` - source file to move
      `targetDir` - target destination
    Returns:
      new location of moved file (since 3.0.0)
    Throws:
      `IOException` - cannot move file.

  - ### moveFileToDir

    public static Path moveFileToDir(@NonNull @NonNull Path sourceFile, @NonNull @NonNull Path targetDir) throws IOException
    Moves a file to a directory. Like `moveFile(File, File)`:
    - If the target directory does not exists, it creates it first.
    - If the target file already exists, it deletes it first.
    - If target file deletion does not work, it will try 10 times, waiting half a second between each try to give a chance to whatever OS lock on the file to go.
    - It throws a IOException if the move failed (as opposed to fail silently).
    Parameters:
      `sourceFile` - source file to move
      `targetDir` - target destination
    Returns:
      new location of moved file
    Throws:
      `IOException` - cannot move file.
    Since:
      3.0.0

  - ### moveFile

    public static void moveFile(@NonNull @NonNull File sourceFile, @NonNull @NonNull File targetFile) throws IOException
    Moves a file to a new file location. This method is different from the `File.renameTo(File)` method in such that:
    - If the target file already exists, it deletes it first.
    - If target file deletion does not work, it will try 10 times, waiting half a second between each try to give a chance to whatever OS lock on the file to go.
    - It throws a IOException if the move failed (as opposed to fail silently).
    - Since 3.0.0, it attempts to create any missing directories in the target path.
    Parameters:
      `sourceFile` - source file to move
      `targetFile` - target destination
    Throws:
      `IOException` - cannot move file.

  - ### moveFile

    public static void moveFile(@NonNull @NonNull Path sourceFile, @NonNull @NonNull Path targetFile) throws IOException
    Moves a file to a new file location. This method is different from the `File.renameTo(File)` method in such that:
    - If the target file already exists, it deletes it first.
    - If target file deletion does not work, it will try 10 times, waiting half a second between each try to give a chance to whatever OS lock on the file to go.
    - It throws a IOException if the move failed (as opposed to fail silently).
    - It attempts to create any missing directories in the target path.
    Parameters:
      `sourceFile` - source file to move
      `targetFile` - target destination
    Throws:
      `IOException` - cannot move file.
    Since:
      3.0.0

  - ### delete

    public static void delete(File file) throws IOException
    Deletes a file or empty directory recursively, in a more robust way. This method applies the following strategies:
    - If file or directory deletion does not work, it will re-try 10 times, waiting 1 second between each try to give a chance to whatever OS lock on the file to go.
    - After a first failed attempt, it invokes `System.gc()` in hope of releasing any handles left on files. This is in relation to a known Java bug mostly occurring on Windows (http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4715154).
    - It throws a IOException if the delete still fails after the 10 attempts (as opposed to fail silently).
    - If file is `null` or does not exist, nothing happens.
    Parameters:
      `file` - file or directory to delete
    Throws:
      `IOException` - cannot delete file.
    Since:
      1.4. Renamed from `deleteFile(File)`

  - ### deleteEmptyDirs

    public static int deleteEmptyDirs(File parentDir) throws IOException
    Recursively deletes all empty directories. The supplied directory itself is also considered for deletion. Directories containing only empty child directories (and no files) are also considered empty and will be deleted.
    Parameters:
      `parentDir` - the directory where to start looking for empty directories
    Returns:
      the number of deleted directories
    Throws:
      `IOException` - error occurred deleting empty directories

  - ### deleteEmptyDirs

    public static int deleteEmptyDirs(Path parentDir) throws IOException
    Recursively deletes all empty directories. The supplied directory itself is also considered for deletion. Directories containing only empty child directories (and no files) are also considered empty and will be deleted.
    Parameters:
      `parentDir` - the directory where to start looking for empty directories
    Returns:
      the number of deleted directories
    Throws:
      `IOException` - error occurred deleting empty directories

  - ### deleteEmptyDirs

    public static int deleteEmptyDirs(File parentDir, Date date) throws IOException

    Recursively deletes all directories that are empty and are older than the given date. If the date is `null`, all empty directories will be deleted, regardless of their date. The supplied directory itself is also considered for deletion.

    Since 3.0.0, directories containing only empty child directories (and no files) are also considered empty and will be deleted.

    Parameters:
      `parentDir` - the directory where to start looking for empty directories
      `date` - the date to compare empty directories against
    Returns:
      the number of deleted directories
    Throws:
      `IOException` - error occurred deleting empty directories
    Since:
      1.3.0

  - ### deleteEmptyDirs

    public static int deleteEmptyDirs(Path parentDir, Date date) throws IOException
    Recursively deletes all directories that are empty and are older than the given date. If the date is `null`, all empty directories will be deleted, regardless of their date. The supplied directory itself is also considered for deletion. Directories containing only empty child directories (and no files) are also considered empty and will be deleted.
    Parameters:
      `parentDir` - the directory where to start looking for empty directories
      `date` - the date to compare empty directories against
    Returns:
      the number of deleted directories
    Throws:
      `IOException` - error occurred deleting empty directories
    Since:
      3.0.0

  - ### createDirsForFile

    public static File createDirsForFile(File file) throws IOException
    Create all parent directories for a file if they do not exists. If they exist already, this method does nothing. This method assumes the last segment is a file or will be a file.
    Parameters:
      `file` - the file to create parent directories for
    Returns:
      The newly created parent directory
    Throws:
      `IOException` - if something went wrong creating the parent directories

  - ### visitAllDirsAndFiles

    public static void visitAllDirsAndFiles(File dir, FileVisitor visitor)
    Visits all files and directories under a directory.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor

  - ### visitAllDirsAndFiles

    public static void visitAllDirsAndFiles(File dir, FileVisitor visitor, FileFilter filter)
    Visits all files and directories under a directory.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor
      `filter` - an optional filter to restrict the files being visited

  - ### visitEmptyDirs

    public static void visitEmptyDirs(File dir, FileVisitor visitor)
    Visits only empty directories under a directory.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor
    Since:
      1.3.0

  - ### visitEmptyDirs

    public static void visitEmptyDirs(File dir, FileVisitor visitor, FileFilter filter)
    Visits only empty directories under a directory.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor
      `filter` - an optional filter to restrict the visited directories
    Since:
      1.3.0

  - ### visitAllDirs

    public static void visitAllDirs(File dir, FileVisitor visitor)
    Visits only directories under a directory.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor

  - ### visitAllDirs

    public static void visitAllDirs(File dir, FileVisitor visitor, FileFilter filter)
    Visits only directories under a directory.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor
      `filter` - an optional filter to restrict the visited directories
    Since:
      1.3.0

  - ### visitAllFiles

    public static void visitAllFiles(File dir, FileVisitor visitor)
    Visits all files (and only files) under a directory, including sub-directories.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor

  - ### visitAllFiles

    public static void visitAllFiles(File dir, FileVisitor visitor, FileFilter filter)
    Visits all files (and only files) under a directory, including sub-directories.
    Parameters:
      `dir` - the directory
      `visitor` - the visitor
      `filter` - an optional filter to restrict the files being visited

  - ### head

    public static String[] head(File file, int numberOfLinesToRead) throws IOException
    Returns the specified number of lines starting from the beginning of a text file. Since 1.5.0, UTF-8 is used as the default encoding.
    Parameters:
      `file` - the file to read lines from
      `numberOfLinesToRead` - the number of lines to read
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### head

    public static String[] head(File file, String encoding, int numberOfLinesToRead) throws IOException
    Returns the specified number of lines starting from the beginning of a text file, using the given encoding.
    Parameters:
      `file` - the file to read lines from
      `encoding` - the file encoding
      `numberOfLinesToRead` - the number of lines to read
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### head

    public static String[] head(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines) throws IOException
    Returns the specified number of lines starting from the beginning of a text file, using the given encoding.
    Parameters:
      `file` - the file to read lines from
      `encoding` - the file encoding
      `numberOfLinesToRead` - the number of lines to read
      `stripBlankLines` - whether to return blank lines or not
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### head

    public static String[] head(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines, Predicate<String> filter) throws IOException
    Returns the specified number of lines starting from the beginning of a text file, using the given encoding.
    Parameters:
      `file` - the file to read lines from
      `encoding` - the file encoding
      `numberOfLinesToRead` - the number of lines to read
      `stripBlankLines` - whether to return blank lines or not
      `filter` - InputStream filter
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### tail

    public static String[] tail(File file, int numberOfLinesToRead) throws IOException
    Returns the specified number of lines starting from the end of a text file. Since 1.5.0, UTF-8 is used as the default encoding.
    Parameters:
      `file` - the file to read lines from
      `numberOfLinesToRead` - the number of lines to read
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### tail

    public static String[] tail(File file, String encoding, int numberOfLinesToRead) throws IOException
    Returns the specified number of lines starting from the end of a text file.
    Parameters:
      `file` - the file to read lines from
      `encoding` - the file encoding
      `numberOfLinesToRead` - the number of lines to read
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### tail

    public static String[] tail(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines) throws IOException
    Returns the specified number of lines starting from the end of a text file.
    Parameters:
      `file` - the file to read lines from
      `encoding` - the file encoding
      `numberOfLinesToRead` - the number of lines to read
      `stripBlankLines` - whether to return blank lines or not
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### tail

    public static String[] tail(File file, String encoding, int numberOfLinesToRead, boolean stripBlankLines, Predicate<String> filter) throws IOException
    Returns the specified number of lines starting from the end of a text file.
    Parameters:
      `file` - the file to read lines from
      `encoding` - the file encoding
      `numberOfLinesToRead` - the number of lines to read
      `stripBlankLines` - whether to return blank lines or not
      `filter` - InputStream filter
    Returns:
      array of file lines
    Throws:
      `IOException` - i/o problem

  - ### createDateDirs

    public static File createDateDirs(File parentDir) throws IOException
    Creates (if not already existing) a series of directories reflecting the current date, up to the day unit, under a given parent directory. For example, a date of 2000-12-31 will create the following directory structure: `/<parentDir>/2000/12/31/`
    Parameters:
      `parentDir` - the parent directory where to create date directories
    Returns:
      the directory representing the full path created
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createDateDirs

    public static File createDateDirs(File parentDir, Date date) throws IOException
    Creates (if not already existing) a series of directories reflecting a date, up to the day unit, under a given parent directory. For example, a date of 2000-12-31 will create the following directory structure: `/<parentDir>/2000/12/31/`
    Parameters:
      `parentDir` - the parent directory where to create date directories
      `date` - the date to create directories from
    Returns:
      the directory representing the full path created
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createDateTimeDirs

    public static File createDateTimeDirs(File parentDir) throws IOException
    Creates (if not already existing) a series of directories reflecting the current date and time, up to the seconds, under a given parent directory. For example, a date of 2000-12-31T13:34:12 will create the following directory structure: `/<parentDir>/2000/12/31/13/34/12/`
    Parameters:
      `parentDir` - the parent directory where to create date directories
    Returns:
      the directory representing the full path created
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createDateTimeDirs

    public static File createDateTimeDirs(File parentDir, Date dateTime) throws IOException
    Creates (if not already existing) a series of directories reflecting a date and time, up to the seconds, under a given parent directory. For example, a date of 2000-12-31T13:34:12 will create the following directory structure: `/<parentDir>/2000/12/31/13/34/12/`
    Parameters:
      `parentDir` - the parent directory where to create date directories
      `dateTime` - the date to create directories from
    Returns:
      the directory representing the full path created
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createDateFormattedDirs

    public static File createDateFormattedDirs(@NonNull @NonNull File parentDir, @NonNull @NonNull Date dateTime, String format) throws IOException
    Creates (if not already existing) a series of directories reflecting the specified date format (from `SimpleDateFormat`), under a given parent directory. Use forward slash in your date format for creating sub-directories. For example, a date of 2000-12-31T13:34:12 with a format of `yyyy/MM/dd/HH-mm-ss` will create the following directory structure: `/<parentDir>/2000/12/31/13-34-12/`
    Parameters:
      `parentDir` - the parent directory where to create date directories
      `dateTime` - the date to create directories from
      `format` - the format to use for creating a date-formatted directory
    Returns:
      the directory representing the full path created
    Throws:
      `IOException` - if the parent directory is not valid
    Since:
      2.0.0

  - ### toDateFormattedDir

    public static File toDateFormattedDir(@NonNull @NonNull File parentDir, @NonNull @NonNull Date dateTime, String format)
    Gets (but does not create) a series of directories reflecting the specified date format (from `SimpleDateFormat`), under a given parent directory. Use forward slash in your date format for creating sub-directories. For example, a date of 2000-12-31T13:34:12 with a format of `yyyy/MM/dd/HH-mm-ss` will create the following directory structure: `/<parentDir>/2000/12/31/13-34-12/`
    Parameters:
      `parentDir` - the parent directory where to create date directories
      `dateTime` - the date to create directories from
      `format` - the format to use for creating a date-formatted directory
    Returns:
      the directory representing the full path created
    Since:
      2.0.0

  - ### createURLDirs

    public static File createURLDirs(File parentDir, URL url) throws IOException

    Creates (if not already existing) a series of directories matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name (not created). The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly.

    Warning: the path created may be too long for some file systems. To avoid issues with file names being too long, consider truncating the generated path by using `createURLDirs(File, URL, boolean)` instead.

    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
    Returns:
      the directory representing the full path created, plus file name
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createURLDirs

    public static File createURLDirs(File parentDir, String url) throws IOException

    Creates (if not already existing) a series of directories matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name (not created). The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly.

    Warning: the path created may be too long for some file systems. To avoid issues with file names being too long, consider truncating the generated path by using `createURLDirs(File, URL, boolean)` instead.

    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
    Returns:
      the directory representing the full path created, plus file name
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createURLDirs

    public static File createURLDirs(File parentDir, URL url, boolean truncate) throws IOException
    Creates (if not already existing) a series of directories matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name (not created). The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly. For the same reason, the full path created can be truncated with a hash code if more than 255 characters. When truncating, the full path to the parent directory must be 200 or less characters (to leave some room for the URL path).
    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
      `truncate` - whether to truncate the directory to 255 characters max.
    Returns:
      the directory representing the full path created, plus file name
    Throws:
      `IOException` - if the parent directory is not valid

  - ### createURLDirs

    public static File createURLDirs(@NonNull @NonNull File parentDir, @NonNull @NonNull String url, boolean truncate) throws IOException
    Creates (if not already existing) a series of directories matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name (not created). The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly. For the same reason, the full path created can be truncated with a hash code if more than 255 characters. When truncating, the full path to the parent directory must be 200 or less characters (to leave some room for the URL path).
    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
      `truncate` - whether to truncate the directory to 255 characters max.
    Returns:
      the directory representing the full path created, plus file name
    Throws:
      `IOException` - if the parent directory is not valid

  - ### toURLDir

    public static File toURLDir(File parentDir, URL url)

    Gets (but does not create) a directory matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name. The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly.

    Warning: the path created may be too long for some file systems. To avoid issues with file names being too long, consider truncating the generated path by using `toURLDir(File, URL, boolean)` instead.

    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
    Returns:
      the directory representing the full path created, plus file name
    Since:
      2.0.0

  - ### toURLDir

    public static File toURLDir(File parentDir, String url)

    Gets (but does not create) a directory matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name. The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly.

    Warning: the path created may be too long for some file systems. To avoid issues with file names being too long, consider truncating the generated path by using `toURLDir(File, URL, boolean)` instead.

    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
    Returns:
      the directory representing the full path created, plus file name
    Since:
      2.0.0

  - ### toURLDir

    public static File toURLDir(@NonNull @NonNull File parentDir, @NonNull @NonNull URL url, boolean truncate)
    Gets (but does not create) a directory matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name. The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly. For the same reason, the full path created can be truncated with a hash code if more than 255 characters. When truncating, the full path to the parent directory must be 200 or less characters (to leave some room for the URL path).
    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
      `truncate` - whether to truncate the directory to 255 characters max.
    Returns:
      the directory representing the full path created, plus file name
    Since:
      2.0.0

  - ### isFile

    public static boolean isFile(File file)
    Null-safe alternative to `File.isFile()`. A `null` file always returns `false`.
    Parameters:
      `file` - the file to test
    Returns:
      `true` if the file is not `null`, exists, and is a regular file
    Since:
      3.0.0

  - ### isFile

    public static boolean isFile(Path file)
    Null-safe alternative to `Files.isRegularFile(Path, java.nio.file.LinkOption...)`. A `null` file always returns `false`.
    Parameters:
      `file` - the file to test
    Returns:
      `true` if the file is not `null`, exists, and is a regular file
    Since:
      3.0.0

  - ### isDirectory

    public static boolean isDirectory(File dir)
    Null-safe alternative to `Files.isDirectory(Path, java.nio.file.LinkOption...)` A `null` directory always returns `false`.
    Parameters:
      `dir` - the directory to test
    Returns:
      `true` if the directory is not `null`, exists, and is a directory
    Since:
      3.0.0

  - ### isDirectory

    public static boolean isDirectory(Path dir)
    Null-safe alternative to `Files.isDirectory(Path, java.nio.file.LinkOption...)` A `null` directory always returns `false`.
    Parameters:
      `dir` - the directory to test
    Returns:
      `true` if the directory is not `null`, exists, and is a directory
    Since:
      3.0.0

  - ### toPath

    public static Path toPath(File file)
    Null-safe alternative to `File.toPath()`. A `null` file returns `null`.
    Parameters:
      `file` - the file to convert
    Returns:
      a `Path` or `null` if file is `null`
    Since:
      3.0.0

  - ### toPaths

    public static Path[] toPaths(File[] files)
    Converts all supplied files to `Path` (`null` entries remain `null`).
    Parameters:
      `files` - the files to convert
    Returns:
      an array of `Path`, never `null`
    Since:
      3.0.0

  - ### toPaths

    public static List<Path> toPaths(Collection<File> files)
    Converts all supplied files to `Path` (`null` entries remain `null`).
    Parameters:
      `files` - the files to convert
    Returns:
      a list of `Path`, never `null`
    Since:
      3.0.0

  - ### toURLDir

    public static File toURLDir(@NonNull @NonNull File parentDir, @NonNull @NonNull String url, boolean truncate)
    Gets (but does not create) a directory matching URL segments, under a given parent directory. The returned file contains the full path to the directories, plus the file name. The file name is the last URL segment (including query string and fragment). Non-alphanumeric characters are escaped to be file-system-friendly. For the same reason, the full path created can be truncated with a hash code if more than 255 characters. When truncating, the full path to the parent directory must be 200 or less characters (to leave some room for the URL path).
    Parameters:
      `parentDir` - the parent directory where to create URL directories
      `url` - the URL to create directories for, with file name.
      `truncate` - whether to truncate the directory to 255 characters max.
    Returns:
      the directory representing the full path created, plus file name
    Since:
      2.0.0