2 * Svjatoslav Commons - shared library of common functionality. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.commons.file;
9 import static java.nio.charset.StandardCharsets.UTF_8;
10 import static java.nio.file.Files.isSymbolicLink;
12 public class IOHelper {
15 * Deletes files and directories recursively. Does not follow symlinks.
17 * @param file directory to delete with entire contents.
18 * @throws IOException if filesystem error happens
20 public static void deleteRecursively(final File file) throws IOException {
22 if (file.isDirectory()) {
23 deleteDirectory(file);
28 if (!file.delete()) throw new IOException("Failed to delete file: " + file);
30 if (isSymbolicLink(file.toPath()) && !file.delete())
31 throw new IOException("Failed to delete symlink: " + file);
35 private static void deleteDirectory(File file) throws IOException {
36 // if file is symlink that points to directory, no not touch content
37 if (!isSymbolicLink(file.toPath())){
38 File[] files = file.listFiles();
40 throw new IOException("Failed to read directory content for: "
43 for (final File subFile : files)
44 deleteRecursively(subFile);
48 throw new IOException("Failed to delete directory: " + file);
51 public static byte[] getFileContents(final File file)
54 final byte[] result = new byte[(int) file.length()];
55 try (final FileInputStream fileInputStream = new FileInputStream(file)) {
56 if (fileInputStream.read(result) != result.length)
57 throw new RuntimeException("Could not read file content:" + file);
63 * Expects file content to be in UTF-8 encoding.
64 * @param file file to read
65 * @return File content
66 * @throws IOException when file reading fails.
68 public static String getFileContentsAsString(final File file)
71 return new String(getFileContents(file), UTF_8);
72 } catch (final UnsupportedEncodingException exception) {
73 throw new RuntimeException(exception);
78 * Compares new file content with old file content. If content in equal,
79 * then leaves file as-is. If content differs, then overrides file with the
82 * @param file file to potentially overwrite
83 * @param newContent new content
84 * @return <code>true</code> if file was overwritten.
85 * @throws FileNotFoundException if file is not found.
86 * @throws IOException if error happens during file IO.
88 public static boolean overwriteFileIfContentDiffers(final File file,
89 final byte[] newContent) throws IOException {
93 if (file.length() == newContent.length) {
95 final byte[] oldContent = getFileContents(file);
97 for (int i = 0; i < newContent.length; i++)
98 if (newContent[i] != oldContent[i])
99 break checkForEquality;
101 // new file content in identical to old content
106 // New content differs from existing. Overwrite file.
107 saveToFile(file, newContent);
111 public static void saveToFile(final File file, final byte[] content)
113 try (final FileOutputStream fos = new FileOutputStream(file)) {
118 public static void saveToFile(final File file, final String content)
120 saveToFile(file, content.getBytes(UTF_8));