| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.uima.pear.util; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.FileReader; |
| import java.io.FilenameFilter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.PrintStream; |
| import java.io.PrintWriter; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Comparator; |
| import java.util.Enumeration; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import java.util.jar.JarEntry; |
| import java.util.jar.JarFile; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipOutputStream; |
| |
| /** |
| * The <code>FileUtil</code> class provides utility methods for working with general files. |
| */ |
| |
| public class FileUtil { |
| |
| /** |
| * The <code>FileTimeComparator</code> class allows comparing 'last modified' time in 2 given |
| * <code>File</code> objects. |
| */ |
| public static class FileTimeComparator implements Comparator<File> { |
| /** |
| * @return A negative integer, zero, or a positive integer as the first argument is less than, |
| * equal to, or greater than the second. |
| * @throws java.lang.ClassCastException |
| * if the arguments' types prevent them from being compared by this |
| * <code>Comparator</code>. |
| */ |
| public int compare(File o1, File o2) throws ClassCastException { |
| long t1 = o1.lastModified(); |
| long t2 = o2.lastModified(); |
| return (t1 >= t2) ? -1 : 1; |
| } |
| |
| /** |
| * @param obj |
| * The reference object with which to compare. |
| * @return <code>true</code> only if the specified object is also a |
| * <code>FileTimeComparator</code>, and it imposes the same ordering as this |
| * comparator. |
| */ |
| public boolean equals(Object obj) { |
| return (obj instanceof FileTimeComparator); |
| } |
| } // FileTimeComparator end |
| |
| /** |
| * The <code>DirFileFilter</code> class allows to filter files based on specified directory path |
| * and filename extension. |
| */ |
| public static class DirFileFilter implements FileFilter { |
| // attributes |
| private String _dirPath; |
| |
| private String _fileExt; |
| |
| /** |
| * Constructs <code>DirFileFilter</code> object for specified directory and file extension. |
| * |
| * @param dirPath |
| * The given directory. |
| * @param fileExt |
| * The given file extension. |
| */ |
| public DirFileFilter(String dirPath, String fileExt) { |
| _dirPath = (dirPath != null) ? dirPath.replace('\\', '/') : null; |
| if (fileExt != null) |
| _fileExt = fileExt.startsWith(".") ? fileExt.toLowerCase() : "." + fileExt.toLowerCase(); |
| else |
| _fileExt = null; |
| } |
| |
| /** |
| * @param file |
| * The given file to be tested. |
| * @return <code>true</code> if the given file should be accepted, <code>false</code> |
| * otherwise. |
| */ |
| public boolean accept(File file) { |
| boolean dirAccepted = true; |
| boolean extAccepted = true; |
| if (_dirPath != null) { |
| String parentDir = file.getParent(); |
| dirAccepted = parentDir != null && parentDir.replace('\\', '/').startsWith(_dirPath); |
| } |
| if (_fileExt != null) { |
| extAccepted = file.getPath().toLowerCase().endsWith(_fileExt); |
| } |
| return dirAccepted && extAccepted; |
| } |
| } // DirFileFilter end |
| |
| /** |
| * The <code>NameFileFilter</code> class allows to filter files based on specified file name. |
| * |
| */ |
| public static class NameFileFilter implements FileFilter { |
| // attributes |
| private String _fileName; |
| |
| /** |
| * Constructs <code>NameFileFilter</code> object for a given file name. |
| * |
| * @param fileName |
| * The given file name for filtering. |
| */ |
| public NameFileFilter(String fileName) { |
| _fileName = fileName.replace('\\', '/'); |
| } |
| |
| /** |
| * @param file |
| * The given file to be tested. |
| * @return <code>true</code> if the given file should be accepted, <code>false</code> |
| * otherwise. |
| */ |
| public boolean accept(File file) { |
| String filePath = file.getAbsolutePath().replace('\\', '/'); |
| if (filePath.endsWith(_fileName)) { |
| if (filePath.length() > _fileName.length()) { |
| char prevChar = filePath.charAt(filePath.length() - _fileName.length() - 1); |
| if (prevChar == ':' || prevChar == '/') |
| return true; |
| } else |
| return true; |
| } |
| return false; |
| } |
| } // NameFileFilter end |
| |
| /** |
| * The <code>ExtFileFilter</code> allows to filter file names based on the specified filename |
| * extension. |
| * |
| */ |
| public static class ExtFilenameFilter implements FilenameFilter { |
| // attributes |
| private String _fileExt; |
| |
| private boolean _ignoreCase; |
| |
| /** |
| * Create instance of the <code>ExtFileFilter</code> class for a given filename extension. By |
| * default, this filename filter is case insensitive. If the given filename extension does not |
| * start from the '.' character, adds this character at the beginning. |
| * |
| * @param fileExt |
| * The given filename extension. |
| */ |
| public ExtFilenameFilter(String fileExt) { |
| this(fileExt, true); |
| } |
| |
| /** |
| * Create instance of the <code>ExtFileFilter</code> class for a given filename extension. If |
| * a given <code>boolean</code> flag is <code>true</code>, this filename filter is case |
| * insensitive, otherwise it's case sensitive. If the given filename extension does not start |
| * from the '.' character, adds this character at the beginning. |
| * |
| * @param fileExt |
| * The given filename extension. |
| * @param ignoreCase |
| * The given 'case sensitivity' flag. |
| */ |
| public ExtFilenameFilter(String fileExt, boolean ignoreCase) { |
| _fileExt = fileExt.startsWith(".") ? fileExt : "." + fileExt; |
| _ignoreCase = ignoreCase; |
| if (ignoreCase) |
| _fileExt = _fileExt.toLowerCase(); |
| } |
| |
| /** |
| * Tests if a specified file should be included in a file list. |
| * |
| * @param dir |
| * The directory in which the file was found. |
| * @param name |
| * The given name of the file. |
| * @return <code>true</code>, if the given file should be included in the list, |
| * <code>false</code> otherwise. |
| */ |
| public boolean accept(File dir, String name) { |
| String fileName = _ignoreCase ? name.toLowerCase() : name; |
| return fileName.endsWith(_fileExt); |
| } |
| } // ExtFilenameFilter end |
| |
| /** |
| * Deletes all files and subdirectories in a given directory. In case of unsuccessful deletion, |
| * calls the <code>deleteOnExit()</code> method to request that files and subdirs are deleted |
| * when the JVM terminates. |
| * |
| * @param directory |
| * The given directory to be cleaned-up. |
| * @return The number of successfully deleted entries in the given directory. |
| * @throws IOException |
| * If an I/O exception occurred. |
| */ |
| public static int cleanUpDirectoryContent(File directory) throws IOException { |
| int counter = 0; |
| File[] allDirFiles = directory.listFiles(); |
| if (allDirFiles != null) { |
| for (int i = 0; i < allDirFiles.length; i++) { |
| File aFile = allDirFiles[i]; |
| if (aFile.isDirectory()) { |
| counter += cleanUpDirectoryContent(aFile); |
| if (aFile.delete()) |
| counter++; |
| else |
| aFile.deleteOnExit(); |
| } else if (aFile.isFile()) { |
| if (aFile.delete()) |
| counter++; |
| else |
| aFile.deleteOnExit(); |
| } |
| } |
| } |
| return counter; |
| } |
| |
| /** |
| * Deletes all files in a given directory. In case of unsuccessful deletion, calls the |
| * <code>deleteOnExit()</code> method to request that files are deleted when the JVM terminates. |
| * |
| * @param directory |
| * The given directory to be cleaned-up. |
| * @return The number of successfully deleted entries in the given directory. |
| * @throws IOException |
| * If an I/O exception occurred. |
| */ |
| public static int cleanUpDirectoryFiles(File directory) throws IOException { |
| int counter = 0; |
| File[] allDirFiles = directory.listFiles(); |
| if (allDirFiles != null) { |
| for (int i = 0; i < allDirFiles.length; i++) { |
| File aFile = allDirFiles[i]; |
| if (aFile.isFile()) { |
| if (aFile.delete()) |
| counter++; |
| else |
| aFile.deleteOnExit(); |
| } |
| } |
| } |
| return counter; |
| } |
| |
| /** |
| * Cleans-up a given directory by keeping the number of files within a given limit. Deletes the |
| * oldest files first. In case of unsuccessful deletion, calls the <code>deleteOnExit()</code> |
| * method to request that files are deleted when the JVM terminates. |
| * |
| * @param directory |
| * The given directory. |
| * @param maxLimit |
| * The given maximum limit of the number of files in the given directory. |
| * @return The number of actually deleted files. |
| * @throws IOException |
| * If an I/O exception occurred. |
| */ |
| public static int cleanUpDirectoryFiles(File directory, int maxLimit) throws IOException { |
| int counter = 0; |
| Collection<File> fileList = createFileList(directory, false); |
| SortedSet<File> sortedFileSet = sortFileListByTime(fileList); |
| if (sortedFileSet.size() > maxLimit) { |
| Iterator<File> list = sortedFileSet.iterator(); |
| int no = 0; |
| while (list.hasNext()) { |
| File file = list.next(); |
| no++; |
| if (no > maxLimit) { |
| if (file.delete()) |
| counter++; |
| else |
| file.deleteOnExit(); |
| } |
| } |
| } |
| return counter; |
| } |
| |
| /** |
| * Computes relative path to a given file from a given reference directory, if both the reference |
| * directory and the file are in the same logical file system (partition). |
| * |
| * @param referenceDir |
| * The given reference directory. |
| * @param file |
| * The given file. |
| * @return The relative path to the given file from the given reference directory, or |
| * <code>null</code>, if the relative path does not exist. |
| * @throws IOException |
| * If an I/O error occurs, which is possible because the construction of the canonical |
| * pathname may require filesystem queries. |
| */ |
| public static String computeRelativePath(File referenceDir, File file) throws IOException { |
| // get canonical path expressions |
| String refPath = referenceDir.getCanonicalPath().replace('\\', '/'); |
| String filePath = file.getCanonicalPath().replace('\\', '/'); |
| // compute relative path from reference dir to file dir-tree |
| StringBuffer relBuffer = new StringBuffer(); |
| while (refPath != null && !filePath.startsWith(refPath)) { |
| relBuffer.append("../"); |
| refPath = (new File(refPath)).getParent(); |
| if (refPath != null) |
| refPath = refPath.replace('\\', '/'); |
| } |
| if (refPath != null) { |
| // construct relative path |
| String subPath = filePath.substring(refPath.length()); |
| if (relBuffer.length() == 0) |
| relBuffer.append("./"); |
| if (subPath.startsWith("/")) |
| relBuffer.append(subPath.substring(1)); |
| else |
| relBuffer.append(subPath); |
| return relBuffer.toString(); |
| } |
| // relative path does not exist |
| return null; |
| } |
| |
| /** |
| * Copies the content of a given source file to a given destination file. |
| * |
| * @param source |
| * The given source file. |
| * @param destination |
| * The given destination file. |
| * @return <code>true</code> if the copy operation completed successfully, <code>false</code> |
| * otherwise. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static boolean copyFile(File source, File destination) throws IOException { |
| boolean completed = false; |
| BufferedInputStream iStream = null; |
| BufferedOutputStream oStream = null; |
| try { |
| iStream = new BufferedInputStream(new FileInputStream(source)); |
| oStream = new BufferedOutputStream(new FileOutputStream(destination)); |
| byte[] block = new byte[4096]; |
| int bCount = 0; |
| while ((bCount = iStream.read(block)) > 0) { |
| oStream.write(block, 0, bCount); |
| } |
| iStream.close(); |
| oStream.close(); |
| completed = true; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (oStream != null) { |
| try { |
| oStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return completed; |
| } |
| |
| /** |
| * Copies the content of a given remote source file to a given destination file. |
| * |
| * @param sourceUrl |
| * The given source file URL. |
| * @param destination |
| * The given destination file. |
| * @return <code>true</code> if the copy operation completed successfully, <code>false</code> |
| * otherwise. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static boolean copyFile(URL sourceUrl, File destination) throws IOException { |
| boolean completed = false; |
| BufferedInputStream iStream = null; |
| BufferedOutputStream oStream = null; |
| try { |
| iStream = new BufferedInputStream(sourceUrl.openStream()); |
| oStream = new BufferedOutputStream(new FileOutputStream(destination)); |
| byte[] block = new byte[4096]; |
| int bCount = 0; |
| while ((bCount = iStream.read(block)) > 0) { |
| oStream.write(block, 0, bCount); |
| } |
| iStream.close(); |
| oStream.close(); |
| completed = true; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (oStream != null) { |
| try { |
| oStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return completed; |
| } |
| |
| /** |
| * Creates list of subdirectories in a given root directory, including all its subdirectories. |
| * |
| * @param rootDir |
| * The given root directory. |
| * @return <code>Collection</code> of <code>File</code> objects, representing subdirectories |
| * in the given root directory and all its subdirectories. |
| * |
| * @throws java.io.IOException |
| * If any I/O exception occurs. |
| */ |
| public static Collection<File> createDirList(File rootDir) throws IOException { |
| return createDirList(rootDir, true); |
| } |
| |
| /** |
| * Creates list of subdirectories in a given root directory. If a given <code>boolean</code> |
| * flag is <code>true</code>, all the subdirectories of the given root directory are also |
| * scanned, otherwise only subdirectories in the given root directory are included. |
| * |
| * @return <code>Collection</code> of <code>File</code> objects, representing subdirectories |
| * in the given root directory. |
| * @param rootDir |
| * The given root directory. |
| * @param includeSubdirs |
| * If <code>true</code>, the returned list includes sub-directories from all |
| * sub-directories of the given root directory, otherwise it includes only |
| * sub-directories from the given root directory itself. |
| * |
| * @exception java.io.IOException |
| * If any I/O exception occurs. |
| */ |
| public static Collection<File> createDirList(File rootDir, boolean includeSubdirs) throws IOException { |
| ArrayList<File> listOfDirs = new ArrayList<File>(); |
| File[] allDirFiles = rootDir.listFiles(); |
| if (allDirFiles == null) |
| throw new FileNotFoundException("invalid directory specified"); |
| for (int i = 0; i < allDirFiles.length; i++) { |
| File aFile = allDirFiles[i]; |
| if (aFile.isDirectory()) { |
| listOfDirs.add(aFile); |
| if (includeSubdirs) |
| listOfDirs.addAll(createDirList(aFile, includeSubdirs)); |
| } |
| } |
| return listOfDirs; |
| } |
| |
| /** |
| * Creates a list of directories in a given archive (JAR) file. The root directory path, used to |
| * represent the directories, is set to the input archive file path without the file name |
| * extension. |
| * |
| * @param archive |
| * The input archive (JAR) file. |
| * @return <code>Collection</code> of <code>File</code> objects, representing directories in |
| * the given archive file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static Collection<File> createDirList(JarFile archive) throws IOException { |
| ArrayList<File> listOfDirs = new ArrayList<File>(); |
| // set root_dir_path = archive_file_path (w/o file name extension) |
| int nameEndIndex = archive.getName().lastIndexOf('.'); |
| String rootDirPath = (nameEndIndex > 0) ? archive.getName().substring(0, nameEndIndex) |
| : archive.getName(); |
| File rootDir = new File(rootDirPath); |
| // add directories to the list |
| Enumeration<JarEntry> entries = archive.entries(); |
| while (entries.hasMoreElements()) { |
| JarEntry entry = entries.nextElement(); |
| File file = new File(rootDir, entry.getName()); |
| if (entry.isDirectory()) |
| listOfDirs.add(file); |
| else { |
| // make sure the parent dir is added |
| File parentDir = file.getParentFile(); |
| while (!parentDir.equals(rootDir)) { |
| if (!listOfDirs.contains(parentDir)) |
| listOfDirs.add(parentDir); |
| parentDir = parentDir.getParentFile(); |
| } |
| } |
| } |
| return listOfDirs; |
| } |
| |
| /** |
| * Creates list of files in a given directory, including all its subdirectories. |
| * |
| * @return <code>Collection</code> of <code>File</code> objects in the given directory, |
| * including all its subdirectories. |
| * @param filesDir |
| * The given directory. |
| * |
| * @exception java.io.IOException |
| * If any I/O exception occurs. |
| */ |
| public static Collection<File> createFileList(File filesDir) throws IOException { |
| return createFileList(filesDir, true); |
| } |
| |
| /** |
| * Creates list of files in a given directory. If a given <code>boolean</code> flag is |
| * <code>true</code>, all the sub-directories of the given directory are also scanned, |
| * otherwise only files in the given directory are included. |
| * |
| * @return <code>Collection</code> of <code>File</code> objects in the given directory. |
| * @param filesDir |
| * The given directory. |
| * @param includeSubdirs |
| * If <code>true</code>, the returned file list includes files from all the |
| * sub-directories of the given directory, otherwise it includes only files from the |
| * given directory itself. |
| * |
| * @exception java.io.IOException |
| * If any I/O exception occurs. |
| */ |
| public static Collection<File> createFileList(File filesDir, boolean includeSubdirs) throws IOException { |
| ArrayList<File> listOfFiles = new ArrayList<File>(); |
| File[] allDirFiles = filesDir.listFiles(); |
| if (allDirFiles == null) |
| throw new FileNotFoundException("invalid directory specified"); |
| for (int i = 0; i < allDirFiles.length; i++) { |
| File aFile = allDirFiles[i]; |
| if (aFile.isDirectory() && includeSubdirs) |
| listOfFiles.addAll(createFileList(aFile, includeSubdirs)); |
| else if (!aFile.isDirectory()) |
| listOfFiles.add(aFile); |
| } |
| return listOfFiles; |
| } |
| |
| /** |
| * Creates a list of files in a given archive (JAR) file. The root directory path, used to |
| * represent the files, is set to the input archive file path without the file name extension. |
| * |
| * @param archive |
| * The input archive (JAR) file. |
| * @return <code>Collection</code> of <code>File</code> objects, representing files in the |
| * given archive file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static Collection<File> createFileList(JarFile archive) throws IOException { |
| ArrayList<File> listOfFiles = new ArrayList<File>(); |
| // set root_dir_path = archive_file_path (w/o file name extension) |
| int nameEndIndex = archive.getName().lastIndexOf('.'); |
| String rootDirPath = (nameEndIndex > 0) ? archive.getName().substring(0, nameEndIndex) |
| : archive.getName(); |
| File rootDir = new File(rootDirPath); |
| // add directories to the list |
| Enumeration<JarEntry> entries = archive.entries(); |
| while (entries.hasMoreElements()) { |
| JarEntry entry = (JarEntry) entries.nextElement(); |
| File file = new File(rootDir, entry.getName()); |
| if (!entry.isDirectory()) |
| listOfFiles.add(file); |
| } |
| return listOfFiles; |
| } |
| |
| /** |
| * Creates a new empty file in a directory specified by the 'java.io.tmpdir' or the 'user.home' |
| * system property, using given prefix and suffix strings to generate its name. For more |
| * information see the documentation on the <code>java.io.File.createTempFile()</code> method. |
| * |
| * @param prefix |
| * The given prefix string to be used in generating the file's name; must be at least |
| * three characters long. |
| * @param suffix |
| * The given suffix string to be used in generating the file's name; may be |
| * <code>null</code>, in which case the suffix ".tmp" will be used. |
| * @return The <code>File</code> object denoting the newly created file. |
| * @throws IOException |
| * If a temporary directory not found or other I/O exception occurred. |
| */ |
| public static File createTempFile(String prefix, String suffix) throws IOException { |
| String tempDirPath = System.getProperty("java.io.tmpdir"); |
| if (tempDirPath == null) |
| tempDirPath = System.getProperty("user.home"); |
| if (tempDirPath == null) |
| throw new IOException("could not find temporary directory"); |
| File tempDir = new File(tempDirPath); |
| if (!tempDir.isDirectory()) |
| throw new IOException("temporary directory not available"); |
| return File.createTempFile(prefix, suffix, tempDir); |
| } |
| |
| /** |
| * Deletes a given directory, including all its subdirectories and files. Returns |
| * <code>true</code> if the deletion was successful, otherwise returns <code>false</code>. In |
| * case of unsuccessful deletion, calls <code>deleteOnExit()</code> method to request that files |
| * and subdirs be deleted when the virtual machine terminates. |
| * |
| * @param dir |
| * The given directory to be deleted. |
| * @return <code>true</code> if the deletion was successful, otherwise <code>false</code>. |
| * @throws java.io.IOException |
| * If any I/O exception occurs. |
| */ |
| public static boolean deleteDirectory(File dir) throws IOException { |
| boolean done = true; |
| // list immediate files/subdirs in this dir |
| File[] fileList = dir.listFiles(); |
| // first, delete plain files and sub-directories (recursive) |
| for (int i = 0; i < fileList.length; i++) { |
| File entry = fileList[i]; |
| if (entry.isDirectory()) |
| done = deleteDirectory(entry); |
| else if (!entry.delete()) { |
| entry.deleteOnExit(); |
| done = false; |
| } |
| } |
| // second, delete the root dir itself |
| if (!dir.delete()) { |
| dir.deleteOnExit(); |
| done = false; |
| } |
| return done; |
| } |
| |
| /** |
| * Extracts all files in a given JAR directory (including all its subdirectories) from a given JAR |
| * file to a given target directory. |
| * |
| * @param jarFile |
| * The given JAR file. |
| * @param dirPath |
| * The given JAR directory. |
| * @param targetDir |
| * The given target directory. |
| * @return Total number of bytes extracted. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static long extractDirectoryFromJar(JarFile jarFile, String dirPath, File targetDir) |
| throws IOException { |
| return extractFilesFromJar(jarFile, targetDir, new DirFileFilter(dirPath, null)); |
| } |
| |
| /** |
| * Extracts all files that have a given extension from a given JAR file to a given target |
| * directory. To extract files without extension, use <code>null</code> as the |
| * <code>fileExt</code> parameter. |
| * |
| * @param jarFile |
| * The given JAR file. |
| * @param fileExt |
| * The given file extension. |
| * @param targetDir |
| * The given target directory. |
| * @return Total number of bytes extracted. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static long extractFilesWithExtFromJar(JarFile jarFile, String fileExt, File targetDir) |
| throws IOException { |
| return extractFilesFromJar(jarFile, targetDir, new DirFileFilter(null, fileExt)); |
| } |
| |
| /** |
| * Extracts all files from a given JAR file to a given target directory. |
| * |
| * @param jarFile |
| * The given JAR file. |
| * @param targetDir |
| * The given target directory. |
| * @return Total number of bytes extracted. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static long extractFilesFromJar(JarFile jarFile, File targetDir) throws IOException { |
| return extractFilesFromJar(jarFile, targetDir, null); |
| } |
| |
| /** |
| * Extracts files from a given JAR file to a given target directory, based on a given |
| * <code>FileFilter</code> object. |
| * |
| * @param jarFile |
| * The given JAR file. |
| * @param targetDir |
| * The given target directory. |
| * @param filter |
| * The given <code>FileFilter</code> object. |
| * @return Total number of bytes extracted. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static long extractFilesFromJar(JarFile jarFile, File targetDir, FileFilter filter) |
| throws IOException { |
| long totalBytes = 0; |
| byte[] block = new byte[4096]; |
| Enumeration<JarEntry> jarList = jarFile.entries(); |
| while (jarList.hasMoreElements()) { |
| JarEntry jarEntry = jarList.nextElement(); |
| if (!jarEntry.isDirectory()) { |
| // check that file is accepted |
| if (filter != null && !filter.accept(new File(jarEntry.getName()))) |
| continue; |
| // extract file |
| File file = new File(targetDir, jarEntry.getName()); |
| // make sure the file directory exists |
| File dir = file.getParentFile(); |
| if (!dir.exists() && !dir.mkdirs()) |
| throw new IOException("could not create directory " + dir.getAbsolutePath()); |
| BufferedInputStream iStream = null; |
| BufferedOutputStream oStream = null; |
| try { |
| iStream = new BufferedInputStream(jarFile.getInputStream(jarEntry)); |
| oStream = new BufferedOutputStream(new FileOutputStream(file)); |
| int bCount = 0; |
| while ((bCount = iStream.read(block)) > 0) { |
| totalBytes += bCount; |
| oStream.write(block, 0, bCount); |
| } |
| iStream.close(); |
| oStream.close(); |
| } finally { |
| // close streams |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (oStream != null) { |
| try { |
| oStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| } |
| return totalBytes; |
| } |
| |
| /** |
| * Constructs an absolute path of a given object, located in a given root directory, based on its |
| * relative path in this directory. |
| * |
| * @param rootDir |
| * The given root directory. |
| * @param relativePath |
| * The given relative path of the object. |
| * @return The absolute path for the given object, located in the given root directory. |
| */ |
| public static String getAbsolutePath(File rootDir, String relativePath) { |
| File object = new File(rootDir, relativePath); |
| return object.getAbsolutePath(); |
| } |
| |
| /** |
| * Identifies a given file name extension. |
| * |
| * @param fileName |
| * The given file name. |
| * @return The file name extension |
| */ |
| public static String getFileNameExtension(String fileName) { |
| StringBuffer buffer = new StringBuffer(); |
| int begIndex = fileName.lastIndexOf('.'); |
| if (begIndex > 0) { |
| buffer.append('.'); |
| for (int i = begIndex + 1; i < fileName.length(); i++) { |
| char ch = fileName.charAt(i); |
| if (Character.isLetterOrDigit(ch)) |
| buffer.append(ch); |
| else |
| break; |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| /** |
| * Returns file size for a given file. |
| * |
| * @param fileLocation |
| * The given file location - local file path or URL. |
| * @return The given file size, if the specified file can be accessed, -1 otherwise. |
| */ |
| public static long getFileSize(String fileLocation) { |
| long fileSize = 0; |
| // choose file size method: local FS or HTTP |
| File file = new File(fileLocation); |
| if (file.isFile()) |
| fileSize = file.length(); |
| else { |
| try { |
| URL fileUrl = new URL(fileLocation); |
| URLConnection urlConn = fileUrl.openConnection(); |
| fileSize = urlConn.getContentLength(); |
| } catch (IOException e) { |
| fileSize = -1; |
| } |
| } |
| return fileSize; |
| } |
| |
| /** |
| * Constructs a relative path of a given object, located in a given root directory, based on its |
| * absolute path. |
| * |
| * @param rootDir |
| * The given root directory. |
| * @param absolutePath |
| * The given absolute path of the object. |
| * @return The relative path of the given object, located in the given root directory. |
| */ |
| public static String getRelativePath(File rootDir, String absolutePath) { |
| String rootDirPath = rootDir.getAbsolutePath().replace('\\', '/'); |
| String objectPath = absolutePath.replace('\\', '/'); |
| if (objectPath.startsWith(rootDirPath)) |
| objectPath = objectPath.substring(rootDirPath.length()); |
| if (objectPath.startsWith("/")) |
| objectPath = objectPath.substring(1); |
| return objectPath; |
| } |
| |
| /** |
| * Makes and attempt to identify possible UTF signatute (BOM) in a given sequence of bytes. |
| * Returns the identified UTF signature name or <code>null</code>, if the signature could not |
| * be identified. For more on UTF and its signatures see <a |
| * href="http://www.unicode.org/faq/utf_bom.html" target="_blank"> FAQ - UTF and BOM</a>. |
| * |
| * @param prefix |
| * The given sequence of bytes to analyze. |
| * @param length |
| * The length of the given sequence of bytes. |
| * @return The UTF signature name or <code>null</code>, if the signature could not be |
| * identified. |
| */ |
| public static String identifyUtfSignature(int[] prefix, int length) { |
| String utfSignature = null; |
| if (length == 3) { |
| // check for UTF-8 signature |
| if (prefix[0] == 0xEF && prefix[1] == 0xBB && prefix[2] == 0xBF) |
| utfSignature = "UTF-8"; |
| } else if (length == 2) { |
| // check for UTF-16 signature |
| if (prefix[0] == 0xFE && prefix[1] == 0xFF) |
| utfSignature = "UTF-16BE"; |
| else if (prefix[0] == 0xFF && prefix[1] == 0xFE) |
| utfSignature = "UTF-16LE"; |
| } else if (length == 4) { |
| // check for UTF-32 signature |
| if (prefix[0] == 0x00 && prefix[1] == 0x00 && prefix[2] == 0xFE && prefix[3] == 0xFF) |
| utfSignature = "UTF-32BE"; |
| else if (prefix[0] == 0xFF && prefix[1] == 0xFE && prefix[2] == 0x00 && prefix[3] == 0x00) |
| utfSignature = "UTF-32LE"; |
| } |
| return utfSignature; |
| } |
| |
| /** |
| * Returns <code>true</code>, if a given text file contains only ASCII characters, otherwise |
| * returns <code>false</code>. |
| * |
| * @param textFile |
| * The given text file. |
| * @return <code>true</code>, if the given text file contains only ASCII characters, |
| * <code>false</code> otherwise. |
| * @throws IOException |
| * If an I/O exception occurred. |
| */ |
| public static boolean isAsciiFile(File textFile) throws IOException { |
| boolean isAscii = true; |
| FileInputStream iStream = null; |
| try { |
| iStream = new FileInputStream(textFile); |
| isAscii = isAsciiStream(iStream); |
| iStream.close(); |
| } catch (IOException exc) { |
| isAscii = false; |
| throw exc; |
| } finally { |
| if (iStream != null) |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| return isAscii; |
| } |
| |
| /** |
| * Returns <code>true</code>, if a given input stream contains only ASCII characters, otherwise |
| * returns <code>false</code>. |
| * |
| * @param iStream |
| * The given input stream. |
| * @return <code>true</code>, if the given input stream contains only ASCII characters, |
| * <code>false</code> otherwise. |
| * @throws IOException |
| * If an I/O exception occurred. |
| */ |
| public static boolean isAsciiStream(InputStream iStream) throws IOException { |
| boolean isAscii = true; |
| try { |
| int nextByte = 0; |
| while ((nextByte = iStream.read()) >= 0) { |
| if (nextByte > 127) { |
| isAscii = false; |
| break; |
| } |
| } |
| } catch (IOException exc) { |
| isAscii = false; |
| throw exc; |
| } |
| return isAscii; |
| } |
| |
| /** |
| * Loads a list of non-empty EOL-delimited strings from a given text stream. |
| * |
| * @param iStream |
| * The given input text stream. |
| * @return The array of non-empty strings loaded from the given text stream. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static String[] loadListOfStrings(BufferedReader iStream) throws IOException { |
| String[] outputArray = null; |
| List<String> outputList = new ArrayList<String>(); |
| String line = null; |
| while ((line = iStream.readLine()) != null) { |
| String string = line.trim(); |
| if (string.length() > 0) |
| outputList.add(string); |
| } |
| if (outputList.size() > 0) { |
| outputArray = new String[outputList.size()]; |
| outputList.toArray(outputArray); |
| } |
| return (outputArray != null) ? outputArray : new String[0]; |
| } |
| |
| /** |
| * Loads a list of non-empty EOL-delimited strings from a given text file using the default file |
| * encoding. |
| * |
| * @param textFile |
| * The given text file. |
| * @return The array of non-empty strings loaded from the given text file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static String[] loadListOfStrings(File textFile) throws IOException { |
| BufferedReader iStream = null; |
| String[] outputArray = null; |
| try { |
| iStream = new BufferedReader(new InputStreamReader(new FileInputStream(textFile))); |
| outputArray = loadListOfStrings(iStream); |
| } catch (IOException exc) { |
| throw exc; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return (outputArray != null) ? outputArray : new String[0]; |
| } |
| |
| /** |
| * Loads a list of non-empty EOL-delimited strings from a given remote text file. |
| * |
| * @param textFileURL |
| * The URL of the given input text file. |
| * @return The array of non-empty strings loaded from the given text file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static String[] loadListOfStrings(URL textFileURL) throws IOException { |
| URLConnection urlConnection = textFileURL.openConnection(); |
| BufferedReader iStream = null; |
| String[] outputArray = null; |
| try { |
| iStream = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); |
| outputArray = loadListOfStrings(iStream); |
| } catch (IOException exc) { |
| throw exc; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return (outputArray != null) ? outputArray : new String[0]; |
| } |
| |
| /** |
| * Loads a specified properties file from a given JAR file. |
| * |
| * @param propFilePath |
| * The given properties file path in the JAR file. |
| * @param jarFile |
| * The given JAR file. |
| * @return <code>Properties</code> object containing loaded properties, or <code>null</code>, |
| * if the properties file was not found in the given JAR file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static Properties loadPropertiesFromJar(String propFilePath, JarFile jarFile) |
| throws IOException { |
| Properties properties = null; |
| String name = propFilePath.replace('\\', '/'); |
| JarEntry jarEntry = jarFile.getJarEntry(name); |
| if (jarEntry != null) { |
| InputStream iStream = null; |
| try { |
| iStream = jarFile.getInputStream(jarEntry); |
| properties = new Properties(); |
| properties.load(iStream); |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| return properties; |
| } |
| |
| /** |
| * Loads a text file associated with a given input stream. |
| * |
| * @param iStream |
| * The given text input stream. |
| * @return The content of the text file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static String loadTextFile(BufferedReader iStream) throws IOException { |
| StringWriter buffer = null; |
| PrintWriter writer = null; |
| try { |
| buffer = new StringWriter(); |
| writer = new PrintWriter(buffer); |
| String line = null; |
| while ((line = iStream.readLine()) != null) |
| writer.println(line); |
| writer.flush(); |
| } catch (IOException exc) { |
| throw exc; |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| /** |
| * Loads a given local text file using the default file encoding. |
| * |
| * @return The content of the text file. |
| * @param textFile |
| * The given text file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static String loadTextFile(File textFile) throws IOException { |
| BufferedReader iStream = null; |
| String content = null; |
| try { |
| iStream = new BufferedReader(new FileReader(textFile)); |
| content = loadTextFile(iStream); |
| } catch (IOException exc) { |
| throw exc; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return content; |
| } |
| |
| /** |
| * Loads a given local text file using a specified file encoding. |
| * |
| * @return The content of the text file. |
| * @param textFile |
| * The given text file. |
| * @param encoding |
| * The given text file encoding name. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static String loadTextFile(File textFile, String encoding) throws IOException { |
| BufferedReader iStream = null; |
| String content = null; |
| try { |
| iStream = new BufferedReader(new InputStreamReader(new FileInputStream(textFile), encoding)); |
| content = loadTextFile(iStream); |
| } catch (IOException exc) { |
| throw exc; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return content; |
| } |
| |
| /** |
| * Loads a given remote text file. |
| * |
| * @param textFileURL |
| * The given text file URL. |
| * @return The content of the text file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static String loadTextFile(URL textFileURL) throws IOException { |
| URLConnection urlConnection = textFileURL.openConnection(); |
| return loadTextFile(urlConnection); |
| } |
| |
| /** |
| * Loads a given remote text file. |
| * |
| * @param urlConnection |
| * The given URL connection. |
| * @return The content of the text file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static String loadTextFile(URLConnection urlConnection) throws IOException { |
| BufferedReader iStream = null; |
| String content = null; |
| try { |
| iStream = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); |
| content = loadTextFile(iStream); |
| } catch (IOException exc) { |
| throw exc; |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return content; |
| } |
| |
| /** |
| * Loads a specified text file from a given JAR file. |
| * |
| * @param filePath |
| * The specified text file path inside the JAR file. |
| * @param jarFile |
| * The given JAR file. |
| * @return The content of the text specified file, or <code>null</code>, if the text file was |
| * not found in the given JAR file. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static String loadTextFileFromJar(String filePath, JarFile jarFile) throws IOException { |
| String content = null; |
| String name = filePath.replace('\\', '/'); |
| JarEntry jarEntry = jarFile.getJarEntry(name); |
| if (jarEntry != null) { |
| BufferedReader iStream = null; |
| try { |
| iStream = new BufferedReader(new InputStreamReader(jarFile.getInputStream(jarEntry))); |
| content = loadTextFile(iStream); |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| return content; |
| } |
| |
| /** |
| * Converts a given input file path into a valid file URL string. |
| * |
| * @param path |
| * The given file path to be converted. |
| * @return The file URL string for the specified file. |
| */ |
| public static String localPathToFileUrl(String path) { |
| // get absolute path |
| File file = new File(path); |
| String absPath = file.getAbsolutePath().replace('\\', '/'); |
| // construct file URL |
| StringBuffer urlBuffer = new StringBuffer("file:///"); |
| urlBuffer.append(absPath.replace(':', '|')); |
| String fileUrlString = urlBuffer.toString().replaceAll(" ", "%20"); |
| URL fileUrl = null; |
| try { |
| fileUrl = new URL(fileUrlString); |
| } catch (MalformedURLException e) { |
| fileUrl = null; |
| } |
| return (fileUrl != null) ? fileUrl.toExternalForm() : fileUrlString; |
| } |
| |
| /** |
| * Moves a given source file to a given destination directory. |
| * |
| * @param source |
| * The given source file. |
| * @param destinationDir |
| * The given destination directory. |
| * @return <code>true</code> if the move operation completed successfully, <code>false</code> |
| * otherwise. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static boolean moveFile(File source, File destinationDir) throws IOException { |
| boolean completed = false; |
| File destination = new File(destinationDir, source.getName()); |
| if (destination.exists()) |
| destination.delete(); |
| if (copyFile(source, destination)) { |
| completed = source.delete(); |
| } |
| return completed; |
| } |
| |
| /** |
| * Replaces all occurences of a given regular expression with a given string in a given text file. |
| * Supports only 1 file encoding - ASCII - for all general text files. Supports 2 encodings - |
| * UTF-8 (ASCII) and UTF-16 for XML files. |
| * |
| * @param textFile |
| * The given text file. |
| * @param subStringRegex |
| * The given regular expression string to be replaced. |
| * @param replacement |
| * The given replacement string. |
| * @return The number of actual string replacements performed. |
| * @throws IOException |
| * If any I/O exception occurs. |
| */ |
| public static int replaceStringInFile(File textFile, String subStringRegex, String replacement) |
| throws IOException { |
| int counter = 0; |
| // for general text file - supporting ASCII encoding only |
| String encoding = "ASCII"; |
| // check file extension |
| int extIndex = textFile.getName().lastIndexOf('.'); |
| String fileExt = (extIndex > 0) ? textFile.getName().substring(extIndex) : null; |
| if (".xml".equalsIgnoreCase(fileExt)) { |
| // for XML file - supporting UTF-8 (ASCII) and UTF-16 encodings |
| String xmlEncoding = XMLUtil.detectXmlFileEncoding(textFile); |
| if (xmlEncoding != null) { |
| encoding = xmlEncoding; |
| } else { |
| encoding = "UTF-8"; |
| } |
| } |
| // load text file, using supported encoding |
| String fileContent = loadTextFile(textFile, encoding); |
| BufferedReader sReader = null; |
| PrintStream fStream = null; |
| boolean done = false; |
| File backupFile = null; |
| // get pattern for given regex |
| Pattern pattern = Pattern.compile(subStringRegex); |
| // format replacement string |
| String replaceWith = StringUtil.toRegExpReplacement(replacement); |
| try { |
| // save backup copy of input file |
| backupFile = new File(textFile.getAbsolutePath() + ".bak"); |
| if (backupFile.exists()) |
| backupFile.delete(); |
| if (!textFile.renameTo(backupFile)) |
| throw new IOException("can't save backup copy of " + textFile.getAbsolutePath()); |
| sReader = new BufferedReader(new StringReader(fileContent)); |
| fStream = new PrintStream(new FileOutputStream(textFile), true, encoding); |
| String srcLine = null; |
| while ((srcLine = sReader.readLine()) != null) { |
| // count pattern matches in the source string |
| Matcher matcher = pattern.matcher(srcLine); |
| while (matcher.find()) |
| counter++; |
| // replace all pattern matches in the source string |
| String resLine = srcLine.replaceAll(subStringRegex, replaceWith); |
| fStream.println(resLine); |
| } |
| fStream.close(); |
| done = true; |
| } catch (IOException exc) { |
| throw exc; |
| } catch (Throwable err) { |
| if (err instanceof IOException) |
| throw new IOException(err.toString() + " in " + textFile.getAbsolutePath()); |
| throw new RuntimeException(err.toString() + " in " + textFile.getAbsolutePath()); |
| } finally { |
| if (sReader != null) { |
| try { |
| sReader.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (fStream != null) { |
| try { |
| fStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (done) { |
| // remove backup file |
| backupFile.delete(); |
| } else { |
| // restore input file |
| textFile.delete(); |
| backupFile.renameTo(textFile); |
| } |
| } |
| return counter; |
| } |
| |
| /** |
| * Sorts a given list of files by the 'last modified' time in the descending order. |
| * |
| * @param fileList |
| * The given list of files. |
| * @return The list of files sorted by the 'last modified' time in the descending order. |
| */ |
| public static SortedSet<File> sortFileListByTime(Collection<File> fileList) { |
| TreeSet<File> set = new TreeSet<File>(new FileTimeComparator()); |
| set.addAll(fileList); |
| return set; |
| } |
| |
| /** |
| * Zips the contents of a given directory. The output ZIP file, by default, is created in the |
| * given directory, and its name is the given directory name with 'zip' extension. |
| * |
| * @param dir2zip |
| * The given directory to be zipped. |
| * @return The output ZIP file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static File zipDirectory(File dir2zip) throws IOException { |
| // construct zipped file path |
| String zipFileName = dir2zip.getName() + ".zip"; |
| File zipFile = new File(dir2zip, zipFileName); |
| return zipDirectory(dir2zip, zipFile); |
| } |
| |
| /** |
| * Zips the contents of a given directory to a given output ZIP file. |
| * |
| * @param dir2zip |
| * The given directory to be zipped. |
| * @param zippedFile |
| * The given output ZIP file. |
| * @return The output ZIP file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static File zipDirectory(File dir2zip, File zippedFile) throws IOException { |
| ZipOutputStream zoStream = null; |
| try { |
| // open compressed output stream |
| zoStream = new ZipOutputStream(new FileOutputStream(zippedFile)); |
| // add output zip file to exclusions |
| File[] excludeFiles = new File[1]; |
| excludeFiles[0] = zippedFile; |
| zipDirectory(dir2zip, zoStream, dir2zip, excludeFiles); |
| } finally { |
| if (zoStream != null) { |
| try { |
| zoStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return zippedFile; |
| } |
| |
| /** |
| * Zips the contents of a given directory to a given ZIP output stream. Paths of file entries in |
| * the ZIP stream are taken relatively to a given reference directory. If the reference directory |
| * is <code>null</code>, the file paths are taken relatively to the given directory to be |
| * zipped. The method allows to specify the list of files (or dirs) that should not be zipped. |
| * |
| * @param dir2zip |
| * The given directory to be zipped. |
| * @param zoStream |
| * The given ZIP output stream. |
| * @param referenceDir |
| * The given reference directory or <code>null</code>. |
| * @param excludeFiles |
| * The given list of files (or dirs) that should not be zipped. |
| * @return The ZIP output stream. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static ZipOutputStream zipDirectory(File dir2zip, ZipOutputStream zoStream, |
| File referenceDir, File[] excludeFiles) throws IOException { |
| byte[] block = new byte[4096]; |
| int inBytes = 0; |
| FileInputStream iStream = null; |
| try { |
| // get list of all files/dirs in the given directory |
| File[] dirFileList = dir2zip.listFiles(); |
| // compress all files and sub-dirs |
| for (int i = 0; i < dirFileList.length; i++) { |
| File entry = dirFileList[i]; |
| // check if this entry is not in the list of exclusions |
| boolean isExcluded = false; |
| for (int n = 0; n < excludeFiles.length; n++) { |
| if (entry.equals(excludeFiles[n])) { |
| isExcluded = true; |
| break; |
| } |
| } |
| if (isExcluded) |
| continue; |
| // for each file - add ZipEntry and compress the file |
| if (entry.isFile()) { |
| // open input stream |
| iStream = new FileInputStream(entry); |
| // put ZipEntry for the file |
| String zipEntryName = (referenceDir != null) ? getRelativePath(referenceDir, entry |
| .getAbsolutePath()) : getRelativePath(dir2zip, entry.getAbsolutePath()); |
| ZipEntry zipEntry = new ZipEntry(zipEntryName); |
| zoStream.putNextEntry(zipEntry); |
| // read input stream and write to output stream |
| while ((inBytes = iStream.read(block)) > 0) |
| zoStream.write(block, 0, inBytes); |
| // close input stream |
| iStream.close(); |
| } else if (entry.isDirectory()) // zip sub-dir recursively |
| zipDirectory(entry, zoStream, referenceDir, excludeFiles); |
| } |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return zoStream; |
| } |
| |
| /** |
| * Zips a given file. The output ZIP file, by default, is created in the same directory, as the |
| * given input file, and has the same name, as the given input file with 'zip' extension. |
| * |
| * @param file2zip |
| * The file to be zipped. |
| * @return The output ZIP file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static File zipFile(File file2zip) throws IOException { |
| // construct zipped file path |
| String zipFileName = file2zip.getName(); |
| int extIndex = zipFileName.lastIndexOf('.'); |
| zipFileName = (extIndex >= 0) ? zipFileName.substring(0, extIndex) + ".zip" : zipFileName |
| + ".zip"; |
| File zipFile = new File(file2zip.getParentFile(), zipFileName); |
| return zipFile(file2zip, zipFile); |
| } |
| |
| /** |
| * Zips a given file to a given output ZIP file. |
| * |
| * @param file2zip |
| * The file to be zipped. |
| * @param zippedFile |
| * The given output ZIP file. |
| * @return The output ZIP file. |
| * @throws IOException |
| * If any I/O exception occurred. |
| */ |
| public static File zipFile(File file2zip, File zippedFile) throws IOException { |
| byte[] block = new byte[4096]; |
| int inBytes = 0; |
| FileInputStream iStream = null; |
| ZipOutputStream oStream = null; |
| try { |
| // open input stream |
| iStream = new FileInputStream(file2zip); |
| // create ZipEntry, using input file name |
| ZipEntry zipEntry = new ZipEntry(file2zip.getName()); |
| // open compressed output stream |
| oStream = new ZipOutputStream(new FileOutputStream(zippedFile)); |
| // add new ZipEntry |
| oStream.putNextEntry(zipEntry); |
| // read input stream and write to output stream |
| while ((inBytes = iStream.read(block)) > 0) |
| oStream.write(block, 0, inBytes); |
| } finally { |
| if (iStream != null) { |
| try { |
| iStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| if (oStream != null) { |
| try { |
| oStream.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| return zippedFile; |
| } |
| } |