/* * The MIT License (MIT) * * Copyright (c) 2015 Ziver Koc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package zutil.io.file; import zutil.StringUtil; import zutil.io.IOUtil; import zutil.log.LogUtil; import java.io.*; import java.net.URISyntaxException; import java.net.URL; import java.util.LinkedList; import java.util.List; import java.util.logging.Logger; import java.util.regex.Matcher; /** * File path utilities * * @author Ziver */ public class FileUtil { private static final Logger logger = LogUtil.getLogger(); /** * Returns a String with a relative path from the given path * * @param file is the file to get a relative path from * @param path is the path * @return A String with a relative path */ public static String relativePath(File file, String path){ if( file == null || path == null ) return null; String absolute = file.getAbsolutePath(); String tmpPath = path.replaceAll( "[/\\\\]", Matcher.quoteReplacement(File.separator)); String relative = absolute.substring( absolute.indexOf(tmpPath)+path.length(), absolute.length()); return relative; } /** * Returns the File object for the given file. * Can not point to files in JAR files. * * @param path is the path to the file (no / if not absolute path) * @return A File object for the file */ public static File find(String path){ try { File file = new File(path); if(file!=null && file.exists()){ return file; } URL url = findURL(path); if(url != null) return new File(url.toURI()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * Copy the contents of a source file to another file. * NOTE: the method will replace the destination file if it exists. * * @param source * @param destination */ public static void copy(File source, File destination) throws IOException{ try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(source)); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(destination));){ IOUtil.copyStream(in, out); } } /** * Returns a nonexistent file that has the same name as the * provided file but appended with a number sequence. * * @param file is the original file or subsequent files returned by this method * @return a new File object with four numbers. * First call will return {FILE_NAME}.0001 and each * subsequent call will return a incremented the number * if the previous file was created. */ public static File getNextFile(File file){ for(int i = 1; i<10000; ++i){ File next = new File(file.getParentFile(), file.getName()+"."+ StringUtil.prefixInt(i, 4)); if(!next.exists()) return next; } return null; } /** * Returns the URL to the given file * * @param path is the path to the file (no / if not absolute path) * @return A URL object for the file * @throws URISyntaxException */ public static URL findURL(String path){ return Thread.currentThread().getContextClassLoader().getResource(path); } /** * Returns a InputStream from the path * * @param path is the path to the file (no / if not absolute path) * @return A InputStream object for the file */ public static InputStream getInputStream(String path){ try { File file = new File(path); if(file!=null && file.exists()){ return new BufferedInputStream( new FileInputStream( file ) ); } return Thread.currentThread().getContextClassLoader() .getResourceAsStream(path); } catch (Exception e) { e.printStackTrace(); } return null; } /** * Reads and returns the content of a file as a String. * * @param file * @return the file content */ public static String getContent(File file) throws IOException{ return new String(getByteContent(file)); } public static byte[] getByteContent(File file) throws IOException { InputStream in = new FileInputStream(file); byte[] data = IOUtil.getContent(in); in.close(); return data; } /** * Reads and returns the content of a file as a String. * * @param url * @return the file content */ public static String getContent(URL url) throws IOException{ InputStream in = url.openStream(); String data = new String(IOUtil.getContent(in)); in.close(); return data; } /** * Replaces the contents of a file with the specified data. * * @param file the file to write the data to * @param data the data to write to the file */ public static void setContent(File file, byte[] data) throws IOException{ OutputStream out = new FileOutputStream(file); out.write(data); out.close(); } /** * Searches the directory and all its subdirectories * * @param dir is the directory to search in * @return a List of files */ public static List search(File dir){ return search(dir, new LinkedList(), true); } /** * Searches the directory and all its subdirectories * * @param dir is the directory to search in * @param fileList an existing List to add all files found * @param recursive if the search should go into subdirectories * @return A List of files */ public static List search(File dir, List fileList, boolean recursive){ return search(dir, new LinkedList(), false, (recursive ? Integer.MAX_VALUE : 0)); } /** * Searches the directory and all its subdirectories * * @param dir is the root directory to start searching from * @param fileList an existing List to add all files found * @param folders is if the method should add folders to the List also * @param recurse if the search should go into subdirectories * @return A List with the files and/or folders */ public static List search(File dir, List fileList, boolean folders, int recurse){ if(recurse<0) return fileList; --recurse; if(folders){ fileList.add( dir ); } File file; String[] temp = dir.list(); if(temp != null){ for(int i=0; i