/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.addthis.basis.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; public final class LessFiles { private static final boolean useStackTraceTempDirname = Parameter.boolValue("debug.tempdir.stacktrace", false); private LessFiles() {} /* Deletes all files and subdirectories under dir. * Returns true if all deletions were successful. * If a deletion fails, the method attempting to complete the delete but returns false. */ public static boolean deleteDir(File dir) { boolean rval = true; if (dir.isDirectory()) { for (File child : dir.listFiles()) { rval = rval && deleteDir(child); } } // The directory is now empty so delete it return rval && dir.delete(); } public static boolean flushDir(File dir) { boolean rval = true; if (dir.isDirectory()) { for (File child : dir.listFiles()) { rval = rval && deleteDir(child); } } return rval; } public static void write(String path, byte[] data, boolean append) throws IOException { File f = new File(path); LessFiles.write(f, data, append); } /** * write bytes to a file with the option to append */ public static void write(File out, byte[] data, boolean append) throws IOException { try (FileOutputStream fot = new FileOutputStream(out, append)) { fot.write(data); } } /** * read all bytes from a file */ public static byte[] read(File in) throws IOException { try (FileInputStream fin = new FileInputStream(in)) { return LessBytes.readFully(fin); } } /** * create a temp directory */ public static File createTempDir() throws IOException { String prefix = "ctd"; if (useStackTraceTempDirname) { StackTraceElement[] stack = Thread.currentThread().getStackTrace(); if (stack.length > 2) { prefix = stack[2].getClassName() + "." + stack[2].getMethodName(); } } return createTempDir(prefix, "tmp"); } public static File createTempDir(String prefix, String suffix) throws IOException { File tmp = File.createTempFile(prefix, suffix); tmp.delete(); tmp.mkdirs(); return tmp; } public static boolean isFileReadable(String filename) { boolean isReadable = false; try { File file = new File(filename); isReadable = file.canRead(); } catch (Exception e) { e.printStackTrace(); } return isReadable; } public static BufferedReader getReader(String filepath) throws IOException { return getReader(new File(filepath)); //will throw NPE if filepath==null } public static BufferedReader getReader(File file) throws IOException { return new BufferedReader(new FileReader(file)); } public static BufferedReader getReader(InputStream is) { return new BufferedReader(new InputStreamReader(is)); } /** */ public static File initDirectory(String dir) { return initDirectory(new File(dir)); } /** * throws RuntimeException if directory doesn't exist and/or can't be created */ public static File initDirectory(File file) { if (file.isDirectory()) { return file; } if (file.isFile()) { throw new RuntimeException("Requested directory '" + file + "' is a file"); } if (!file.mkdirs()) { throw new RuntimeException("Unable to create directory '" + file + "'"); } return file; } /** * throws IOException if directory doesn't exist and/or can't be created */ public static File openDirectory(File file) throws IOException { if (file.isDirectory()) { return file; } if (file.isFile()) { throw new IOException("Requested directory '" + file + "' is a file"); } if (!file.mkdirs()) { throw new IOException("Unable to create directory '" + file + "'"); } return file; } public static String setupUIDFile(File dir, String uidFileName) throws IOException { File uid = new File(dir, uidFileName); String guid = CUID.createCUID(); if (uid.exists() && uid.isFile() && uid.canRead()) { try (FileReader fr = new FileReader(uid)) { BufferedReader br = new BufferedReader(fr); guid = br.readLine(); if ((guid == null) || guid.trim().isEmpty()) { guid = CUID.createCUID(); } } } try (FileOutputStream fos = new FileOutputStream(uid)) { fos.write(guid.getBytes()); fos.flush(); } return guid; } /** * truncate a file to the specified length */ public static void truncate(File file, long size) throws IOException { if (file == null) { return; } if (size > file.length()) { throw new IllegalArgumentException("file " + file.getName() + " cannot be truncated, desired size (" + size + ") is greater than file length."); } try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) { raf.setLength(size); } } public static void expandPath(String root, List<File> expanded) { int off = 0; if ((off = root.indexOf("/*")) >= 0) { String left = root.substring(0, off); String right = off + 3 < root.length() ? root.substring(off + 3, root.length()) : ""; File dir = new File(left); if (dir.exists() && dir.isDirectory()) { File[] files = dir.listFiles(); for (File file : files) { expandPath(left + "/" + file.getName() + "/" + right, expanded); } } } else { expanded.add(new File(root)); } } public static File[] matchFiles(String dirTemplate) { ArrayList<File> expanded = new ArrayList<>(); expandPath(dirTemplate, expanded); return expanded.toArray(new File[expanded.size()]); } public static String getSuffix(File file) { return getSuffix(file.getName()); } public static String getSuffix(String fname) { int suffix_pos = fname.lastIndexOf('.'); if (suffix_pos == -1) { return ""; } return fname.substring(1 + suffix_pos); } public static File replaceSuffix(File file, String new_suffix) { String name = file.getName(); int suffix_pos = name.lastIndexOf('.'); return new File(file.getParent(), suffix_pos == -1 ? name + new_suffix : name.substring(0, suffix_pos) + new_suffix); } public static long directorySize(File directory) throws IOException { long size = 0; for (File file : directory.listFiles()) { if (file.isFile()) { size += file.length(); } else { size += directorySize(directory); } } return size; } }