// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: // /cvs/distapps/openmap/src/openmap/com/bbn/openmap/util/FileUtils.java,v // $ // $RCSfile: FileUtils.java,v $ // $Revision: 1.6 $ // $Date: 2006/07/10 23:22:28 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; 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.net.URL; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.Adler32; import java.util.zip.CheckedOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileFilter; import com.bbn.openmap.Environment; public class FileUtils { protected static Logger logger = Logger.getLogger("com.bbn.openmap.util.FileUtils"); public static String getFilePathToSaveFromUser(String title) { OpenFileRunnable runnable = new OpenFileRunnable(title, null) { public void run() { JFileChooser chooser = getChooser(title); if (fileFilter != null) { chooser.setFileFilter(fileFilter); } int state = chooser.showSaveDialog(null); result = handleResponse(chooser, state); } }; runnable.invoke(); return runnable.getResult(); } public static String getFilePathToOpenFromUser(String title) { return getFilePathToOpenFromUser(title, null); } public static String getFilePathToOpenFromUser(String title, FileFilter ff) { OpenFileRunnable runnable = new OpenFileRunnable(title, ff); runnable.invoke(); return runnable.getResult(); } public static String getPathToOpenFromUser(String title, FileFilter ff, int fileSelectionMode, String acceptButtonText) { OpenPathRunnable runnable = new OpenPathRunnable(title, ff, fileSelectionMode, acceptButtonText); runnable.invoke(); return runnable.getResult(); } static class OpenFileRunnable implements Runnable { String title; FileFilter fileFilter; String result; OpenFileRunnable(String title, FileFilter ff) { this.title = title; this.fileFilter = ff; } public void run() { JFileChooser chooser = getChooser(title); if (fileFilter != null) { chooser.setFileFilter(fileFilter); } int state = chooser.showOpenDialog(null); this.result = handleResponse(chooser, state); } String getResult() { return result; } void invoke() { try { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeAndWait(OpenFileRunnable.this); } else { run(); } } catch (Exception e) { if (logger.isLoggable(Level.FINE)) { e.printStackTrace(); } } } } static class OpenPathRunnable extends OpenFileRunnable { int fileSelectionMode; String acceptButtonText; OpenPathRunnable(String title, FileFilter ff, int fileSelectionMode, String acceptButtonText) { super(title, ff); this.fileSelectionMode = fileSelectionMode; this.acceptButtonText = acceptButtonText; } public void run() { JFileChooser chooser = getChooser(title); chooser.setFileSelectionMode(fileSelectionMode); if (fileFilter != null) { chooser.setFileFilter(fileFilter); } int state = chooser.showDialog(null, acceptButtonText); this.result = handleResponse(chooser, state); } } public static JFileChooser getChooser(String title) { // setup the file chooser File startingPoint = new File(Environment.get("lastchosendirectory", System.getProperty("user.home"))); JFileChooser chooser = new JFileChooser(startingPoint); chooser.setDialogTitle(title); return chooser; } public static String handleResponse(JFileChooser chooser, int state) { String ret = null; try { // only bother trying to read the file if there is one // for some reason, the APPROVE_OPTION said it was a // boolean during compile and didn't work in this next // statement if ((state != JFileChooser.CANCEL_OPTION) && (state != JFileChooser.ERROR_OPTION)) { ret = chooser.getSelectedFile().getCanonicalPath(); int dirIndex = ret.lastIndexOf(File.separator); if (dirIndex >= 0) { // store the selected file for later Environment.set("lastchosendirectory", ret.substring(0, dirIndex)); } } } catch (IOException ioe) { JOptionPane.showMessageDialog(null, ioe.getMessage(), "Error picking file", JOptionPane.ERROR_MESSAGE); ioe.printStackTrace(); } return ret; } /** * Copy a file to another location, byte-wise. * * @param fromFile * the File to copy from. * @param toFile * the File to copy to. * @param bufSize * the byte size of the transfer buffer. * @throws IOException * Thrown if anything goes wrong. */ public static void copy(File fromFile, File toFile, int bufSize) throws IOException { FileInputStream fis = new FileInputStream(fromFile); FileOutputStream fos = new FileOutputStream(toFile); if (bufSize <= 0) { bufSize = 1024; } byte[] bytes = new byte[bufSize]; int numRead; while ((numRead = fis.read(bytes)) > 0) { fos.write(bytes, 0, numRead); } fis.close(); fos.close(); } /** * Delete a file or a directory, including its content. * * @param file file to delete * @throws IOException if there's a problem */ public static void deleteFile(File file) throws IOException { if (file.isDirectory()) { // directory is empty, then delete it if (file.list().length == 0) { file.delete(); System.out.println("Directory is deleted : " + file.getAbsolutePath()); } else { // list all the directory contents String files[] = file.list(); for (String temp : files) { // construct the file structure File fileDelete = new File(file, temp); // recursive delete deleteFile(fileDelete); } // check the directory again, if empty then delete it if (file.list().length == 0) { file.delete(); } } } else { // if file, then delete it file.delete(); } } /** * Create a zip file containing the given File. * * @param zipFileName The path to the zip file. If it doesn't end in .zip, * .zip will be added to it. * @param toBeZipped The Path of the file/directory to be zipped. * @throws IOException if there's a problem * @throws FileNotFoundException if there's a problem */ public static void saveZipFile(String zipFileName, File toBeZipped) throws IOException, FileNotFoundException { try { if (!zipFileName.endsWith(".zip")) { zipFileName += ".zip"; } File zipFile = new File(zipFileName); if (!zipFile.getParentFile().exists()) { zipFile.getParentFile().mkdirs(); } FileOutputStream fos = new FileOutputStream(zipFile); ZipOutputStream zoStream = new ZipOutputStream(fos); // zoStream.setMethod(ZipOutputStream.STORED); writeZipEntry(toBeZipped, zoStream, toBeZipped.getParent().length() + 1); zoStream.close(); } catch (SecurityException se) { logger.warning("Security Exception caught while creating " + zipFileName); } } /** * Create a zip file containing the files in the list. The entries will not * have their parent's file names in their path, they are stored with the * given file at the root of the zip/jar. * * @param zipFileName The path to the zip/jar file. * @param toBeZipped The List of files to be placed in the zip/jar. * @throws IOException if there's a problem * @throws FileNotFoundException if there's a problem */ public static void saveZipFile(String zipFileName, List<File> toBeZipped) throws IOException, FileNotFoundException { try { File zipFile = new File(zipFileName); if (!zipFile.getParentFile().exists()) { zipFile.getParentFile().mkdirs(); } FileOutputStream fos = new FileOutputStream(zipFile); CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32()); ZipOutputStream zoStream = new ZipOutputStream(new BufferedOutputStream(checksum)); // ZipOutputStream zoStream = new ZipOutputStream(fos); // zoStream.setMethod(ZipOutputStream.STORED); for (File file : toBeZipped) { writeZipEntry(file, zoStream, file.getParent().length() + 1); } zoStream.close(); } catch (SecurityException se) { logger.warning("Security Exception caught while creating " + zipFileName); } } /** * Writes a file to the jar stream. * * @param toBeZipped the file to be written * @param zoStream the stream to write it to, prepared for the * ZipFile/JarFile * @param prefixTrimLength The number of characters to trim off the absolute * path of the file to be zipped. Can be useful to adjust this to * adjust the directory depth of the entry for when it is unpacked. * If less than 0, only the file name will be used. * @throws IOException if there's a problem */ public static void writeZipEntry(File toBeZipped, ZipOutputStream zoStream, int prefixTrimLength) throws IOException { if (toBeZipped.isDirectory()) { File[] files = toBeZipped.listFiles(); for (int i = 0; i < files.length; i++) { writeZipEntry(files[i], zoStream, prefixTrimLength); } } else { if (logger.isLoggable(Level.FINE)) { logger.fine(toBeZipped + ", " + toBeZipped.getAbsolutePath().substring(prefixTrimLength) + ")"); } writeZipEntry(toBeZipped, zoStream, prefixTrimLength < 0 ? toBeZipped.getName() : toBeZipped.getAbsolutePath().substring(prefixTrimLength)); } } protected static void writeZipEntry(File fromFile, ZipOutputStream zoStream, String entryName) throws IOException { entryName = entryName.replace('\\', '/'); // long size = fromFile.length(); ZipEntry zEntry = new ZipEntry(entryName); // zEntry.setSize(size); // zEntry.setCrc(0);// Don't know what it these values are // right now, but zero works... zoStream.putNextEntry(zEntry); FileInputStream fis = new FileInputStream(fromFile); byte[] bytes = new byte[1024]; int numRead; // CRC32 checksum = new CRC32(); while ((numRead = fis.read(bytes)) > 0) { zoStream.write(bytes, 0, numRead); // checksum.update(bytes, 0, numRead); } // zEntry.setCrc(checksum.getValue()); zoStream.closeEntry(); fis.close(); } /** * Unpack a zip file. * * @param zipFileName * The path name of the zip file to unpack. * @param toDir * the directory to put the unpacked files in. * @param deleteAfter * flag to delete the zip file when complete. */ public static void openZipFile(String zipFileName, File toDir, boolean deleteAfter) { if (zipFileName != null) { try { InputStream in; if (!toDir.exists()) { toDir.mkdirs(); } URL zipurl = PropUtils.getResourceOrFileOrURL(zipFileName); if (zipurl != null) { in = new BufferedInputStream(zipurl.openStream()); if (logger.isLoggable(Level.FINE)) { logger.fine(" unzipping " + zipFileName); } ZipInputStream zin = new ZipInputStream(in); ZipEntry e; while ((e = zin.getNextEntry()) != null) { if (e.isDirectory()) { new File(toDir, e.getName()).mkdirs(); } else { if (logger.isLoggable(Level.FINE)) { logger.fine(" unzipping " + e.getName()); } unzip(zin, new File(toDir, e.getName())); } } zin.close(); if (deleteAfter) { if (logger.isLoggable(Level.FINE)) { logger.fine("unzipping complete, deleting zip file"); } File file = new File(zipurl.getFile()); if (file.exists()) { file.delete(); } } else if (logger.isLoggable(Level.FINE)) { logger.fine("unzipping complete, leaving zip file"); } return; } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } protected static void unzip(ZipInputStream zin, File f) throws IOException { final int BUFFER = 2048; FileOutputStream out = new FileOutputStream(f); byte[] b = new byte[BUFFER]; int len = 0; BufferedOutputStream dest = new BufferedOutputStream(out, BUFFER); while ((len = zin.read(b, 0, BUFFER)) != -1) { dest.write(b, 0, len); } dest.flush(); dest.close(); } }