Handy function for writing file
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / file / IOHelper.java
index b742d56..01c0837 100755 (executable)
@@ -1,46 +1,51 @@
 /*
- * Svjatoslav Commons - shared library of common functionality.
- * Copyright ©2012-2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 3 of the GNU Lesser General Public License
- * or later as published by the Free Software Foundation.
+ * Svjatoslav Commons - shared library of common functionality. Author: Svjatoslav Agejenko.
+ * This project is released under Creative Commons Zero (CC0) license.
  */
-
 package eu.svjatoslav.commons.file;
 
 import java.io.*;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.nio.file.Files.isSymbolicLink;
+
 public class IOHelper {
 
     /**
-     * Deletes files and directories recursively. WARNING!!! Follows symlinks!!!
+     * Deletes files and directories recursively. Does not follow symlinks.
      *
      * @param file directory to delete with entire contents.
      * @throws IOException if filesystem error happens
      */
     public static void deleteRecursively(final File file) throws IOException {
+
         if (file.isDirectory()) {
+            deleteDirectory(file);
+            return;
+        }
 
+        if (file.isFile()){
+            if (!file.delete()) throw new IOException("Failed to delete file: " + file);
+        } else {
+            if (isSymbolicLink(file.toPath()) && !file.delete())
+                throw new IOException("Failed to delete symlink: " + file);
+        }
+    }
+
+    private static void deleteDirectory(File file) throws IOException {
+        // if file is symlink that points to directory, no not touch content
+        if (!isSymbolicLink(file.toPath())){
             File[] files = file.listFiles();
             if (files == null)
-                throw new RuntimeException("Failed to read directory content for: "
+                throw new IOException("Failed to read directory content for: "
                         + file);
 
             for (final File subFile : files)
                 deleteRecursively(subFile);
-
-            if (!file.delete())
-                throw new RuntimeException("Failed to delete directory: "
-                        + file);
-
-            return;
         }
 
-        if (file.isFile())
-            if (!file.delete())
-                throw new FileNotFoundException("Failed to delete file: "
-                        + file);
+        if (!file.delete())
+            throw new IOException("Failed to delete directory: " + file);
     }
 
     public static byte[] getFileContents(final File file)
@@ -54,10 +59,16 @@ public class IOHelper {
         return result;
     }
 
+    /**
+     * Expects file content to be in UTF-8 encoding.
+     * @param file file to read
+     * @return File content
+     * @throws IOException when file reading fails.
+     */
     public static String getFileContentsAsString(final File file)
             throws IOException {
         try {
-            return new String(getFileContents(file), "UTF-8");
+            return new String(getFileContents(file), UTF_8);
         } catch (final UnsupportedEncodingException exception) {
             throw new RuntimeException(exception);
         }
@@ -104,4 +115,9 @@ public class IOHelper {
         }
     }
 
+    public static void saveToFile(final File file, final String content)
+            throws IOException {
+        saveToFile(file, content.getBytes(UTF_8));
+    }
+
 }