Class IOHelper

java.lang.Object
eu.svjatoslav.commons.file.IOHelper

public class IOHelper extends Object
Utility class for common file system operations.

This class provides static methods for file I/O operations including: reading and writing files, recursive directory deletion, and smart file overwriting that only writes when content differs.

Key features:

  • Safe recursive deletion that does not follow symbolic links
  • UTF-8 encoding for text file operations
  • Smart overwriting that avoids unnecessary disk writes
  • Simple byte array and string-based file operations

Example usage:


 // Write and read a text file
 File file = new File("example.txt");
 IOHelper.saveToFile(file, "Hello, World!");
 String content = IOHelper.getFileContentsAsString(file);

 // Smart overwriting - only writes if content differs
 IOHelper.overwriteFileIfContentDiffers(file, "New content".getBytes());

 // Delete a directory recursively
 File directory = new File("temp");
 IOHelper.deleteRecursively(directory);
 

Note on symbolic links: The deleteRecursively(File) method handles symbolic links safely. When a symlink points to a directory, the directory's contents are not deleted - only the symlink itself is removed. This prevents accidental deletion of data outside the intended scope.

  • Method Details

    • deleteRecursively

      public static void deleteRecursively(File file) throws IOException
      Deletes a file or directory recursively. Does not follow symbolic links.

      This method safely handles:

      • Regular files - deleted directly
      • Directories - contents deleted first, then the directory itself
      • Symbolic links - the link is deleted, not the target
      • Symbolic links to directories - link deleted, target directory untouched

      The non-following of symlinks is an important safety feature. If a symlink points to an important directory outside the scope of deletion, that directory's contents remain safe.

      Example usage:

      
       // Delete a file
       IOHelper.deleteRecursively(new File("temp.txt"));
      
       // Delete a directory with all contents
       IOHelper.deleteRecursively(new File("tempDir"));
      
       // Delete a symlink (target remains intact)
       IOHelper.deleteRecursively(new File("linkToOtherDir"));
       
      Parameters:
      file - the file, directory, or symbolic link to delete. Must not be null.
      Throws:
      IOException - if a filesystem error occurs during deletion, such as permission denied or file in use.
    • getFileContents

      public static byte[] getFileContents(File file) throws IOException
      Reads the entire contents of a file as a byte array.

      The file must exist and its size must fit in memory. This method is suitable for small to medium-sized files. For large files, consider using streaming approaches instead.

      The returned array has exactly the same length as the file size.

      Parameters:
      file - the file to read. Must exist and be readable.
      Returns:
      the complete file contents as a byte array.
      Throws:
      IOException - if an I/O error occurs, such as file not found or permission denied.
      RuntimeException - if the file could not be fully read (unexpected EOF).
    • getFileContentsAsString

      public static String getFileContentsAsString(File file) throws IOException
      Reads the entire contents of a file as a UTF-8 encoded string.

      The file content is assumed to be UTF-8 encoded. This is the standard encoding for text files in most modern applications.

      The file must exist and its size must fit in memory. This method is suitable for text files of reasonable size.

      Example usage:

      
       File file = new File("config.txt");
       String config = IOHelper.getFileContentsAsString(file);
       
      Parameters:
      file - the file to read. Must exist and be readable.
      Returns:
      the file contents as a UTF-8 decoded string.
      Throws:
      IOException - if an I/O error occurs during file reading.
    • overwriteFileIfContentDiffers

      public static boolean overwriteFileIfContentDiffers(File file, byte[] newContent) throws IOException
      Compares new content with existing file content and overwrites only if different.

      This method performs a byte-by-byte comparison with the existing file content. If the content is identical, no write operation occurs, saving disk I/O and preserving file timestamps.

      This is useful for:

      • Configuration files that might not change
      • Generated source code to avoid triggering rebuilds
      • Any case where unnecessary writes should be avoided

      If the file does not exist, it is created and the content is written.

      Example usage:

      
       byte[] newConfig = generateConfig().getBytes();
       boolean changed = IOHelper.overwriteFileIfContentDiffers(
           new File("config.xml"), newConfig);
       if (changed) {
           System.out.println("Configuration updated");
       } else {
           System.out.println("No changes needed");
       }
       
      Parameters:
      file - the file to potentially overwrite. If it does not exist, it will be created.
      newContent - the new content to potentially write. Must not be null.
      Returns:
      true if the file was overwritten (content differed or file was created), false if the content was identical and no write occurred.
      Throws:
      FileNotFoundException - if the file cannot be found for reading (when comparing existing content).
      IOException - if an I/O error occurs during reading or writing.
    • saveToFile

      public static void saveToFile(File file, byte[] content) throws IOException
      Saves byte content to a file, overwriting any existing content.

      This method writes the complete byte array to the file. If the file exists, it is overwritten. If it does not exist, it is created.

      This is a straightforward write operation - use overwriteFileIfContentDiffers(File, byte[]) if you want to avoid unnecessary writes when content is unchanged.

      Parameters:
      file - the file to write to. Parent directories must exist.
      content - the byte content to write. Must not be null.
      Throws:
      IOException - if an I/O error occurs during writing.
    • saveToFile

      public static void saveToFile(File file, String content) throws IOException
      Saves string content to a file using UTF-8 encoding, overwriting any existing content.

      The string is encoded as UTF-8 before writing. If the file exists, it is overwritten. If it does not exist, it is created.

      This is a convenient method for writing text files:

      
       IOHelper.saveToFile(new File("output.txt"), "Hello, World!");
       
      Parameters:
      file - the file to write to. Parent directories must exist.
      content - the string content to write, encoded as UTF-8. Must not be null.
      Throws:
      IOException - if an I/O error occurs during writing.