| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // which accompanies this distribution, and is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // Contributors: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.common.utils; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.net.URL; |
| import java.nio.CharBuffer; |
| import java.nio.MappedByteBuffer; |
| import java.nio.channels.FileChannel; |
| import java.nio.channels.FileLock; |
| import java.nio.channels.OverlappingFileLockException; |
| import java.nio.charset.Charset; |
| import java.nio.charset.CharsetDecoder; |
| import java.util.List; |
| import java.util.Locale; |
| |
| /** |
| * Utility class for managing directories and files. |
| * |
| * @author Kelvin Low |
| * @since 1.0 |
| */ |
| public class FileUtil { |
| |
| /** |
| * Platform-specific line separator. |
| */ |
| public static final String LINE_SEP = System.getProperty("line.separator"); //$NON-NLS-1$ |
| |
| /** |
| * Platform-specific file separator. |
| */ |
| public static final String FILE_SEP = System.getProperty("file.separator"); //$NON-NLS-1$ |
| |
| /** |
| * Platform-specific line separator length. |
| */ |
| public static final int LINE_SEP_LENGTH = LINE_SEP.length(); |
| |
| /** |
| * UNC path prefix. |
| */ |
| public static final String UNC_PATH_PREFIX = "\\\\"; //$NON-NLS-1$ |
| |
| /** |
| * UNC path prefix length. |
| */ |
| public static final int UNC_PATH_PREFIX_LENGTH = UNC_PATH_PREFIX.length(); |
| |
| /** |
| * ISO-8859-1 encoding. |
| */ |
| public static final String ENCODING_ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$ |
| |
| /** |
| * UTF-8 encoding. |
| */ |
| public static final String ENCODING_UTF_8 = "UTF-8";//$NON-NLS-1$ |
| |
| /** |
| * Private constructor to prevent this class from being instantiated. All |
| * methods in this class should be static. |
| */ |
| private FileUtil() { |
| } |
| |
| /** |
| * Returns the absolute path for the given file or directory. |
| * |
| * @param file |
| * The given file or directory. |
| * @return The absolute path of the given file or directory. |
| */ |
| public static String getAbsolutePath(File file) { |
| return file.getAbsolutePath().replace('\\', '/'); |
| } |
| |
| /** |
| * Returns the absolute path for the given file or directory. |
| * |
| * @param file |
| * The given file or directory name. |
| * @return The absolute path of the given file or directory. |
| */ |
| public static String getAbsolutePath(String file) { |
| return getAbsolutePath(new File(file)); |
| } |
| |
| /** |
| * Returns the absolute path for the given URL. |
| * |
| * @param url |
| * The given URL. |
| * @return The absolute path of the given URL. |
| */ |
| public static String getAbsolutePath(URL url) { |
| String pathName = url.getFile().substring(1); |
| String result = NetUtil.decodeUrl(pathName, null); |
| return result; |
| } |
| |
| /** |
| * Returns the parent directory of the given path. |
| * |
| * @param path |
| * The path name. |
| * @return The name of the parent directory. |
| */ |
| public static String getParentDirectory(String path) { |
| return (new File(path)).getParent(); |
| } |
| |
| /** |
| * Returns the file name and extension from the given path. |
| * |
| * @param path |
| * The path name. |
| * @return The file name and the file extension. |
| */ |
| public static String getFileName(String path) { |
| return getFileName(path, true); |
| } |
| |
| /** |
| * Returns the file name from the given path, with or without the file |
| * extension. |
| * |
| * @param path |
| * The path name. |
| * @param withExtension |
| * If true, include the file extension in the result. |
| * @return The file name with or without the file extension. |
| */ |
| public static String getFileName(String path, boolean withExtension) { |
| String normalizedPath = path.replace('\\', '/'); |
| |
| int prefixLength = 0; |
| if (normalizedPath.startsWith(NetUtil.FILE_URI_PREFIX)) { |
| prefixLength = NetUtil.FILE_URI_PREFIX_LENGTH; |
| } else if (normalizedPath.startsWith(NetUtil.HTTP_URI_PREFIX)) { |
| prefixLength = NetUtil.HTTP_URI_PREFIX_LENGTH; |
| } |
| |
| String fileName; |
| int index = normalizedPath.lastIndexOf("/"); //$NON-NLS-1$ |
| if (index < prefixLength) { |
| fileName = normalizedPath.substring(prefixLength); |
| } else { |
| fileName = path.substring(index + 1); |
| } |
| |
| if (withExtension) { |
| return fileName; |
| } |
| |
| index = fileName.indexOf("."); //$NON-NLS-1$ |
| return (index > 0) ? fileName.substring(0, index) : fileName; |
| } |
| |
| /** |
| * Returns the relative path for the target path from the base path. |
| * |
| * @param path |
| * The target path. |
| * @param basePath |
| * The base path. |
| * @return The relative path. |
| */ |
| public static String getRelativePathToBase(File path, File basePath) { |
| try { |
| String dir = path.toURL().toExternalForm(); |
| String baseDir = basePath.toURL().toExternalForm(); |
| StringBuffer result = new StringBuffer(); |
| if (dir.indexOf(baseDir) == 0) { |
| String delta = dir.substring(baseDir.length()); |
| for (int i = 0; i < delta.length(); i++) { |
| if (delta.charAt(i) == '/') { |
| result.append("../"); //$NON-NLS-1$ |
| } |
| } |
| } |
| return result.toString(); |
| } catch (Exception e) { |
| return ""; //$NON-NLS-1$ |
| } |
| } |
| |
| public static String getRelativePath(File path, File basePath) { |
| try { |
| String dir = path.toURL().toExternalForm(); |
| String baseDir = appendSeparator(basePath.toURL().toExternalForm(), |
| "/"); //$NON-NLS-1$ |
| StringBuffer result = new StringBuffer(); |
| while (dir.indexOf(baseDir) == -1) { |
| basePath = basePath.getParentFile(); |
| baseDir = appendSeparator(basePath.toURL().toExternalForm(), |
| "/"); //$NON-NLS-1$ |
| result.append("../"); //$NON-NLS-1$ |
| } |
| if (dir.indexOf(baseDir) == 0) { |
| String delta = dir.substring(baseDir.length()); |
| result.append(delta); |
| } |
| return result.toString(); |
| } catch (Exception e) { |
| return ""; //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Appends the platform specific path separator to the end of the given |
| * path. |
| * |
| * @param path |
| * The path name. |
| * @return The path name appended with the platform specific path separator. |
| */ |
| public static String appendSeparator(String path) { |
| return appendSeparator(path, File.separator); |
| } |
| |
| /** |
| * Appends the given path separator to the end of the given path. |
| * |
| * @param path |
| * The path name. |
| * @param separator |
| * The path separator. |
| * @return The path name appended with the given separator. |
| */ |
| public static String appendSeparator(String path, String separator) { |
| return path.endsWith(separator) ? path : path + separator; |
| } |
| |
| /** |
| * Removes the ending path separator from the given path. |
| * |
| * @param path |
| * The path name. |
| * @return The path name minus the platform specific path separator. |
| */ |
| public static String removeSeparator(String path) { |
| return path.endsWith(File.separator) ? path.substring(0, |
| path.length() - 1) : path; |
| } |
| |
| /** |
| * Removes the ending path separator from the given path. |
| * |
| * @param path |
| * The path name. |
| * @return The path name minus the path separator "\\" or "/". |
| */ |
| public static String removeAllSeparator(String path) { |
| return path.endsWith("/") || path.endsWith("\\") ? path.substring(0, path.length() - 1) : path; //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Removes the ending path separator from the given path. |
| * |
| * @param path |
| * The path name. |
| * @param separator |
| * The path separator. |
| * @return The path name minus the separator. |
| */ |
| public static String removeSeparator(String path, String separator) { |
| return path.endsWith(separator) ? path.substring(0, path.length() - 1) |
| : path; |
| } |
| |
| /** |
| * Replaces the file name with another in the given path. |
| * |
| * @param path |
| * The path name. |
| * @param oldFileName |
| * The old file name. |
| * @param newFileName |
| * The new file name. |
| * @return The new path name with the new file name. |
| */ |
| public static String replaceFileName(String path, String oldFileName, |
| String newFileName) { |
| int index = path.lastIndexOf(oldFileName); |
| return path.substring(0, index) + newFileName; |
| } |
| |
| /** |
| * Replaces the file extension with another in the given path. |
| * |
| * @param path |
| * The path name. |
| * @param oldFileExt |
| * The old file extension. |
| * @param newFileExt |
| * The new file extension. |
| * @return The new path with the new file extension. |
| */ |
| public static String replaceExtension(String path, String oldExt, |
| String newExt) { |
| int index = path.lastIndexOf(oldExt); |
| return path.substring(0, index) + newExt; |
| } |
| |
| /** |
| * Returns the locale-specific path of a base path. |
| * |
| * @param path |
| * The base path name. |
| * @param localeStr |
| * The locale string. |
| * @return The locale-specific path. |
| */ |
| public static String getLocalePath(String path, String localeStr) { |
| if (StrUtil.isBlank(localeStr)) { |
| return path; |
| } |
| String fileName = getFileName(path); |
| return replaceFileName(path, fileName, localeStr + "/" + fileName); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the locale-specific path of a base path. |
| * |
| * @param path |
| * The base path name. |
| * @param locale |
| * The locale object. |
| * @return The locale-specific path. |
| */ |
| public static String getLocalePath(String path, Locale locale) { |
| return locale == null ? path : getLocalePath(path, locale.toString()); |
| } |
| |
| /** |
| * Writes the given text to a text file. |
| * |
| * @param fileName |
| * The target file name. |
| * @param text |
| * The text to write. |
| * @return true if the given text is written successfully to file. |
| */ |
| public static boolean writeFile(String filename, String text) { |
| FileWriter writer = null; |
| try { |
| writer = new FileWriter(filename); |
| writer.write(text); |
| writer.flush(); |
| } catch (IOException e) { |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| return true; |
| } catch (Exception e) { |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Write the given text to a file with UTF-8 encoding. |
| * |
| * @param fileName |
| * The target file name. |
| * @param text |
| * The text to write. |
| * @return true if the given text is written successfully to file. |
| */ |
| public static boolean writeUTF8File(String filename, String text) { |
| OutputStreamWriter writer = null; |
| FileOutputStream fileOut = null; |
| try { |
| fileOut = new FileOutputStream(filename); |
| writer = new OutputStreamWriter(fileOut, ENCODING_UTF_8); |
| writer.write(text); |
| writer.flush(); |
| fileOut.flush(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| return true; |
| } catch (Exception e) { |
| } |
| } |
| if (fileOut != null) { |
| try { |
| fileOut.close(); |
| return true; |
| } catch (Exception e) { |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Write the content of the given URI to the given output stream. |
| * |
| * @param uri |
| * The source URI. |
| * @param output |
| * The output stream. |
| */ |
| public static void writeFile(String uri, OutputStream output) |
| throws IOException { |
| if (uri == null) { |
| return; |
| } |
| |
| InputStream input = null; |
| try { |
| input = NetUtil.getInputStream(uri); |
| int bytesRead; |
| byte[] buf = new byte[4096]; |
| while ((bytesRead = input.read(buf, 0, 4096)) > 0) { |
| output.write(buf, 0, bytesRead); |
| } |
| output.flush(); |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| |
| /** |
| * Write the content of the given URI to the given PrintWriter. |
| * |
| * @param uri |
| * The source URI. |
| * @param writer |
| * The PrintWriter obejct. |
| */ |
| public static void writeFile(String uri, PrintWriter pw) throws IOException { |
| if (uri == null) { |
| return; |
| } |
| |
| InputStreamReader input = null; |
| try { |
| input = new InputStreamReader(NetUtil.getInputStream(uri)); |
| int charsRead; |
| char[] buf = new char[4096]; |
| while ((charsRead = input.read(buf, 0, 4096)) > 0) { |
| pw.write(buf, 0, charsRead); |
| } |
| pw.flush(); |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| |
| /** |
| * Recursively delete all sub-directories and files in the given directory. |
| * Does not delete the given directory. |
| * |
| * @param dir |
| * The directory containing the sub-directories and files. |
| * @return boolean true if delete successful |
| */ |
| public static boolean deleteAllFiles(String dir) { |
| boolean ret = true; |
| File targetDir = new File(dir); |
| File[] files = targetDir.listFiles(); |
| if (files != null) { |
| for (int i = 0; i < files.length; i++) { |
| if (files[i].isDirectory()) { |
| ret = ret && deleteAllFiles(files[i].getAbsolutePath()); |
| } |
| ret = ret && files[i].delete(); |
| } |
| } |
| |
| return ret; |
| } |
| |
| /** |
| * Copies the content of the source file to the target file. |
| * |
| * @param srcFile |
| * The source file or path. |
| * @param tgtFile |
| * The target file or path. |
| */ |
| public static void copyFile(File srcFile, File tgtFile) throws IOException { |
| if (srcFile.equals(tgtFile)) |
| return; |
| |
| if (!srcFile.exists() || !srcFile.canRead()) { |
| return; |
| } |
| |
| if (tgtFile.exists() && !tgtFile.canWrite()) { |
| return; |
| } |
| |
| if (!srcFile.isFile()) { |
| File[] files = srcFile.listFiles(); |
| if (files != null) { |
| for (int i = 0; i < files.length; i++) { |
| copyFile(files[i], tgtFile); |
| } |
| } |
| return; |
| } |
| |
| FileInputStream src = null; |
| FileOutputStream tgt = null; |
| try { |
| src = new FileInputStream(srcFile); |
| if (tgtFile.isFile()) { |
| tgt = new FileOutputStream(tgtFile); |
| } else { |
| String srcPath = srcFile.toURL().toString(); |
| int index = srcPath.lastIndexOf("/"); //$NON-NLS-1$ |
| String srcFileName = srcPath.substring(index + 1); |
| tgt = new FileOutputStream(new File(tgtFile, srcFileName)); |
| } |
| byte[] buffer = new byte[4096]; |
| int bytes_read; |
| while ((bytes_read = src.read(buffer)) != -1) { |
| tgt.write(buffer, 0, bytes_read); |
| } |
| } finally { |
| if (src != null) { |
| try { |
| src.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (tgt != null) { |
| try { |
| tgt.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| |
| /** |
| * Copies the content of the source file to the target file. |
| * |
| * @param srcFileName |
| * The source file name. |
| * @param tgtFileName |
| * The target file name. |
| */ |
| public static void copyFile(String srcFileName, String tgtFileName) |
| throws IOException { |
| copyFile(new File(srcFileName), new File(tgtFileName)); |
| } |
| |
| /** |
| * Copies the content of a directory to another directory. |
| * |
| * @param srcDirName |
| * The source directory name. |
| * @param tgtDirName |
| * The target directory name. |
| */ |
| public static void copyDir(String srcDirName, String tgtDirName) |
| throws IOException { |
| copyFile(new File(srcDirName), new File(tgtDirName)); |
| } |
| |
| /** |
| * Copies one file to another - operates ONLY on files, not on directories. |
| * |
| * @param source |
| * @param dest |
| * @throws IOException |
| */ |
| public static void copyfile(File source, File dest) throws IOException { |
| if (source.equals(dest)) |
| return; |
| |
| FileInputStream input = null; |
| FileOutputStream output = null; |
| |
| try { |
| input = new FileInputStream(source); |
| FileChannel in = input.getChannel(); |
| if (!dest.exists()) { |
| dest.getParentFile().mkdirs(); |
| } |
| output = new FileOutputStream(dest); |
| FileChannel out = output.getChannel(); |
| out.transferFrom(in, 0, source.length()); |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (IOException e) { |
| } |
| } |
| if (output != null) { |
| try { |
| output.close(); |
| } catch (IOException e) { |
| } |
| } |
| } |
| } |
| |
| public static void copydirectory(File sourceDir, File destDir) |
| throws IOException { |
| if (!sourceDir.exists() || !destDir.exists()) { |
| return; |
| } |
| |
| if (!sourceDir.isDirectory() || !destDir.isDirectory()) { |
| return; |
| } |
| |
| File[] files = sourceDir.listFiles(); |
| if (files != null) { |
| for (int i = 0; i < files.length; i++) { |
| // calc destination name |
| String destName = destDir |
| + File.separator |
| + files[i].getAbsolutePath().substring( |
| sourceDir.getAbsolutePath().length() + 1); |
| if (files[i].isFile()) { |
| // copy the file |
| copyfile(files[i], new File(destName)); |
| } else if (files[i].isDirectory()) { |
| // copy directory recursively |
| File destFile = new File(destName); |
| destFile.mkdirs(); |
| copydirectory(files[i], destFile); |
| } |
| } |
| } |
| |
| } |
| |
| // for some reason, this guy locks the file, if you try to update the file, |
| // got the following exception |
| // java.io.FileNotFoundException: |
| // (The requested operation cannot be performed on a file with a user-mapped |
| // section open) |
| // need to handle later |
| public static CharBuffer readFile(File file) throws IOException { |
| FileInputStream input = null; |
| CharBuffer charBuffer = null; |
| try { |
| input = new FileInputStream(file); |
| FileChannel inChannel = input.getChannel(); |
| int length = (int) inChannel.size(); |
| MappedByteBuffer byteBuffer = inChannel.map( |
| FileChannel.MapMode.READ_ONLY, 0, length); |
| Charset charset = Charset.forName(ENCODING_ISO_8859_1); |
| CharsetDecoder decoder = charset.newDecoder(); |
| charBuffer = decoder.decode(byteBuffer); |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (IOException e) { |
| } |
| } |
| } |
| return charBuffer; |
| } |
| |
| public static StringBuffer readFile(File file, String encoding) |
| throws IOException { |
| |
| StringBuffer result = new StringBuffer(); |
| FileInputStream fis = null; |
| InputStreamReader reader = null; |
| try { |
| char[] buffer = new char[1024]; |
| fis = new FileInputStream(file); |
| reader = new InputStreamReader(fis, encoding); |
| int size; |
| while ((size = reader.read(buffer, 0, 1024)) > 0) { |
| result.append(buffer, 0, size); |
| } |
| } finally { |
| if (fis != null) { |
| fis.close(); |
| } |
| |
| if (reader != null) { |
| reader.close(); |
| } |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Uses Java 1.4's FileLock class to test for a file lock |
| * |
| * @param file |
| * @return |
| */ |
| public static boolean isFileLocked(File file) { |
| boolean isLocked = false; |
| FileOutputStream input = null; |
| FileLock lock = null; |
| |
| try { |
| input = new FileOutputStream(file); |
| FileChannel fileChannel = input.getChannel(); |
| |
| lock = fileChannel.tryLock(); |
| |
| if (lock == null) |
| isLocked = true; |
| else |
| lock.release(); |
| } catch (Exception e) { |
| if (e instanceof SecurityException) |
| // Can't write to file. |
| isLocked = true; |
| else if (e instanceof FileNotFoundException) |
| isLocked = false; |
| else if (e instanceof IOException) |
| isLocked = true; |
| // OverlappingFileLockException means that this JVM has it locked |
| // therefore it is not locked to us |
| else if (e instanceof OverlappingFileLockException) |
| isLocked = false; |
| // Could not get a lock for some other reason. |
| else |
| isLocked = true; |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (Exception ex) { |
| } |
| } |
| } |
| return isLocked; |
| } |
| |
| /** |
| * Locks a file for the current JVM. Will create the file if it does not |
| * exist |
| * |
| * @param file |
| * @return a FileLock object, or null if file could not be locked |
| */ |
| public static FileLock lockFile(File file) { |
| FileOutputStream input = null; |
| FileLock lock = null; |
| try { |
| input = new FileOutputStream(file); |
| FileChannel fileChannel = input.getChannel(); |
| lock = fileChannel.tryLock(); |
| |
| return lock; |
| } catch (Exception e) { |
| // Could not get a lock for some reason. |
| return null; |
| } finally { |
| if (input != null) { |
| try { |
| input.close(); |
| } catch (Exception ex) { |
| } |
| } |
| } |
| } |
| |
| /** |
| * get all files in the specified path |
| * @param path, absolute path of a folder |
| * @param fileList List the list to collect the Files |
| * @param recursive boolean, if true find the files in sub folders as well |
| */ |
| public static void getAllFiles(File path, List fileList, boolean recursive) |
| { |
| // get all files in the specified folder |
| if (path.isDirectory()) |
| { |
| File[] files = path.listFiles(); |
| if (files != null) |
| { |
| for (int i = 0; i < files.length; i++) |
| { |
| if ( files[i].isFile() ) |
| { |
| fileList.add(files[i]); |
| } |
| else if (recursive) |
| { |
| getAllFiles(files[i], fileList, recursive); |
| } |
| } |
| } |
| } |
| } |
| |
| } |