/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package modmanager.utility; import modmanager.business.ManagerOptions; import javax.swing.JFileChooser; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.ArrayList; import java.util.Random; /** * * @author Shirkit */ public class FileUtils { /** * Loads a text file to a String. * @param f file to be read. * @param encoding encode to be used for loading the file, or null to none. * @return a String containing the content of the read file. * @throws IOException if an I/O error occurs. */ public static String loadFile(File f, String encoding) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader br = null; try { if (encoding != null) { br = new BufferedReader(new InputStreamReader(new FileInputStream(f), encoding)); } else { br = new BufferedReader(new InputStreamReader(new FileInputStream(f))); } for (String line = br.readLine(); line != null; line = br.readLine()) { sb.append(line).append("\n"); } } finally { if (br != null) { try { br.close(); } catch (IOException ex) { } } } return sb.toString(); } /** * Copies a source file to target destination * @param source file to be copied. * @param destination file where source will be copied to. * @throws FileNotFoundException if couldn't read/access the source file or if couldn't access(if exists)/create destination file. * @throws IOException if an I/O error occurs. */ public static void copyFile(File source, File destination) throws FileNotFoundException, IOException { if (destination.exists()) { updatePermissions(destination); } else { destination.createNewFile(); } FileInputStream in = new FileInputStream(source); FileOutputStream out = new FileOutputStream(destination); copyInputStream(in, out); in.close(); out.close(); } /** * Copies a source file to target destination * @param source file to be copied. * @param destination file where source will be copied to. * @throws FileNotFoundException if couldn't read/access the source file or if couldn't access(if exists)/create destination file. * @throws IOException if an I/O error occurs. */ public static void copyFile(File source, String destination) throws FileNotFoundException, IOException { copyFile(source, new File(destination)); } /** * Copies a source file to target destination * @param source file to be copied. * @param destination file where source will be copied to. * @throws FileNotFoundException if couldn't read/access the source file or if couldn't access(if exists)/create destination file. * @throws IOException if an I/O error occurs. */ public static void copyFile(String source, String destination) throws FileNotFoundException, IOException { copyFile(new File(source), new File(destination)); } /** * Writes the content of a byte array to a target file. * @param file byte array with the content of the file to be written. * @param destination destination file where the file will be written * @throws FileNotFoundException if couldn't access, write or create the <b>destination</b> param file. * @throws IOException if an I/O error occurs. */ public static void writeFile(byte[] file, File destination) throws FileNotFoundException, IOException { if (destination.exists()) { updatePermissions(destination); } else { destination.createNewFile(); } ByteArrayInputStream in = new ByteArrayInputStream(file); FileOutputStream out = new FileOutputStream(destination); copyInputStream(in, out); in.close(); out.close(); } /** * Writes a file with the BOM bytes in the start of the file. * @param file byte array with the content of the file to be written. * @param destination destination file where the file will be written * @throws FileNotFoundException if couldn't access, write or create the <b>destination</b> param file. * @throws IOException - if an I/O error occurs. */ public static void writeFileWithBom(byte[] file, File destination) throws FileNotFoundException, IOException { boolean writeBom = true; if (destination.exists()) { updatePermissions(destination); FileInputStream fis = new FileInputStream(destination); if (fis.available() > 3 && fis.read() == 239 && fis.read() == 187 && fis.read() == 191) { writeBom = false; } } else { destination.createNewFile(); if (file[0] == 239 && file[1] == 187 && file[2] == 191) { writeBom = false; } else if ((0xff & file[0]) == 239 && (0xff & file[1]) == 187 && (0xff & file[2]) == 191) { writeBom = false; } } ByteArrayInputStream in = new ByteArrayInputStream(file); FileOutputStream out = new FileOutputStream(destination); if (writeBom) { out.write(239); out.write(187); out.write(191); } copyInputStream(in, out); in.close(); out.close(); } /** * Copies the files inside a folder to destination folder. If destinationFolder doesn't exist, it will be created. * @param sourceFolder Folder with the files to be copied * @param destinationFolder Destination folder for the files to be copied on. * @throws FileNotFoundException if a file wasn't found or destination file already exists and couldn't be written on. * @throws IOException if a radom I/O occurred. */ public static void copyFolderToFolder(File sourceFolder, File destinationFolder) throws FileNotFoundException, IOException { File[] fileList = sourceFolder.listFiles(); for (int i = 0; i < fileList.length; i++) { File sourceFile = fileList[i]; File destinationFile = new File(destinationFolder, sourceFile.getName()); if (sourceFile.isDirectory()) { if (destinationFile.mkdirs()) { copyFolderToFolder(sourceFile, destinationFile); } } else { copyFile(sourceFile, destinationFile); } } } /** * Attemps to delete a directory recursively. It first must delete the files inside this folder, so if any of those files failed to delete, all process will fail. * @param dir Folder to be deleted. * @return true if deleted folder and all files within it, false otherwise. */ public static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // The directory is now empty so delete it return dir.delete(); } /** * * @param in Generic InputStream for the content to be copied. * @param out Generic OutputStream for the content to be put on. * @throws IOException if a random I/O Exception occurred. */ public static void copyInputStream(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int len; while (((len = in.read(buffer)) >= 0)) { out.write(buffer, 0, len); } out.flush(); } /** * Tries to update the permissions of the target file with the possible {@code File} permissions methods. * @param f file to be updated. */ public static void updatePermissions(File f) { f.setWritable(true); f.setReadable(true); } private static ArrayList<File> temporaryFolders = new ArrayList<File>(); /** * This method attemps to clean up all the temporary folder folders created during this execution by the method referenced in this doc. * @see FileUtils.#generateTempFolder(boolean) */ public static void deleteTemporaryFolders() { for (int i = 0; i < temporaryFolders.size(); i++) { File file = temporaryFolders.get(i); deleteDir(file); } } /** * This method generates a temporary folder for the Manager operations. It attemps to create a folder in %TEMPDIR%\HoN Mod Manager\%RANDOM FOLDER% directory. If it fails, an exception is thrown. * @param deleteOnExit - wheter the temporary folder should be deleted on exit or not. * @return a File with the path for the created folder. * @throws SecurityException is failed to create a folder. */ public static File generateTempFolder(boolean deleteOnExit) { Random r = new Random(); File tempFolder = null; for (int i = 0; i < 100; i++) { tempFolder = new File(getManagerTempFolder() + File.separator + r.nextLong()); if (tempFolder.exists()) { if (!tempFolder.delete()) { } else { i = 100; } } else { i = 100; } } if (tempFolder == null) { throw new SecurityException(); } tempFolder.mkdirs(); if (deleteOnExit) { temporaryFolders.add(tempFolder); tempFolder.deleteOnExit(); } return tempFolder; } /** * This method returns the folder located in Operational System's temporary folder {@code "tmpdir/Hon Mod Manager"} * @return the temp folder. */ public static File getManagerTempFolder() { File tempFolder = new File(System.getProperty("java.io.tmpdir") + File.separator + "HoN Mod Manager"); if (!tempFolder.exists()) { tempFolder.mkdirs(); } return tempFolder; } // Caching static File perpetualFolder = null; /** * This method returns the folder that it's content won't be clean by the operational systems from times to times. It is Operational System dependent. * @return the target folder. */ public static File getManagerPerpetualFolder() { // Caching if (perpetualFolder != null) { return perpetualFolder; } File folder = null; if (OS.isLinux()) { folder = new File(System.getProperty("user.home") + File.separator + ".Heroes of Newerth" + File.separator + "All-In HoN ModManager"); if (!folder.exists()) { if (!folder.mkdirs()) { return new File(ManagerOptions.MANAGER_FOLDER); } } } if (OS.isWindows()) { folder = new File(new JFileChooser().getFileSystemView().getDefaultDirectory(), "Heroes of Newerth" + File.separator + "All-In HoN ModManager"); if (!folder.exists()) { if (!folder.mkdirs()) { return new File(ManagerOptions.MANAGER_FOLDER); } } } if (OS.isMac()) { return new File(ManagerOptions.MANAGER_FOLDER); } perpetualFolder = folder; return folder; } }