/** * FileHeap v1.00 * Copyright (c) 2002 by Derek Park * Released under the GNU GPL */ import java.io.*; import java.util.Vector; /** * A utility class. FileHeap will copy all of the files from a set of source * directories with a certain extension or certain extensions, and copy them * to a destination directory, renaming on-the-fly to avoid name clashes. * i.e. While copying directories foo and bar, FileHeap might encounter two * files named "HelloWorld.ogg". The file from directory foo will be copied as * "HelloWorld.ogg" and the file from directory bar will be copied as * "HelloWorld (2).ogg". To allow all extensions, omit the "-e" and the * extension list. * * Usage: * java FileHeap -s foo bar -d bas -e .ogg .mp3 * * running FileHeap with no arguments will display this message */ public class FileHeap { File [] sources; File destination; String [] extensions; private final static String usagemessage = "\n" + "-----\n" + "FileHeap v1.00\n" + "Copyright (c) 2002 by Derek Park\n" + "Released under the GNU GPL\n\n" + "FileHeap is a utility class. FileHeap will copy all of the files\n" + "from a set of source directories with a certain extension or\n" + "certain extensions, and copy them to a destination directory,\n" + "renaming on-the-fly to avoid name clashes. i.e. While copying\n" + "directories foo and bar, FileHeap might encounter two files named\n" + "\"HelloWorld.ogg\". The file from directory foo will be copied as\n" + "\"HelloWorld.ogg\" and the file from directory bar will be copied\n" + "as \"HelloWorld (2).ogg\". To allow all extensions, omit the\n" + "\"-e\" and the extension list.\n\n" + "Usage:\n" + "java FileHeap -s foo bar -d bas -e .ogg .mp3\n\n" + "running FileHeap with no arguments will display this message\n" + "-----"; /** * Accepts a list of directories as sources, a directory as a destination, * and a list of acceptable file extensions. The extensions should * include the extension separation character. e.g. ".txt", ".gif", ".mp3" * * @param sources an array of Files representing source directories * @param destination a File representing a destination directory * @param extensions an array of Strings representing acceptable file * extensions, or null, to accept all extensions * * @throws IllegalArgumentException if the Files passed are not directories * or if the Strings passed are not valid extensions */ protected FileHeap(File [] sources, File destination, String [] extensions) throws IllegalArgumentException { this.sources = sources; this.destination = destination; this.extensions = extensions; for (int i = 0; i < sources.length; i++) { if (!sources[i].isDirectory()) { throw new IllegalArgumentException(sources[i] + " is not a directory"); } if (!sources[i].exists()) { throw new IllegalArgumentException(sources[i] + " does not exist"); } } if (!destination.isDirectory()) { throw new IllegalArgumentException(destination + " is not a directory"); } if (!destination.exists()) { throw new IllegalArgumentException(destination + " does not exist"); } if (extensions != null) { for (int i = 0;i < extensions.length; i++) { if (extensions[i].lastIndexOf('.') != 0) { throw new IllegalArgumentException(extensions[i] + " is not a properly formatted extension"); } } } } /** * Called to start the copying of the files into the "Heap" directory. * * @throws IOException if an unexpected IO error occurs */ protected void heap() throws IOException { File [] filelist = buildFileList(sources,extensions); System.out.println("\n\n-----\n"); for (int i = 0; i < filelist.length; i++) { System.out.println(filelist[i].toString() + ":"); File dest = new File(destination, filelist[i].getName()); // another file already has that name if(!dest.createNewFile()) { // loop until we find one that doesn't exist for (int j = 2; !dest.createNewFile(); j++) { dest = new File(destination, name(filelist[i]) + " (" + j + ")" + ext(filelist[i])); } } System.out.println(dest + " created"); copyFile(filelist[i],dest); System.out.println(filelist[i] + " copied to " + dest); System.out.println("-----\n"); } } private static String ext (File f) { return f.getName().substring(f.getName().lastIndexOf('.')); } private static String name (File f) { return f.getName().substring(0,f.getName().lastIndexOf('.')); } /** * Builds an array of Files containing all the actual files * found in the parameter, as well as all the files found in any * subdirectories of the parameter. No Files which represent * directories are included in the list returned. * * @param f an array of Files from which to build a full file * list. * @param exts an array of strings representing each valid filename * extension to accept (e.g. ".mp3", ".gif", ".txt") or null, to accept * all extensions * * @return a File array representing a file list. */ protected static File [] buildFileList(File [] f, String[] exts) { Vector v = recurseSubdirectories(f,exts); File [] fileList = new File[v.size()]; for(int i = 0; i < fileList.length; i++) { fileList[i] = (File)v.elementAt(i); } return fileList; } private static Vector recurseSubdirectories(File[] f, String[] exts) { Vector v = new Vector(100); String s; for(int i = 0; i < f.length; i++) { if(f[i].isDirectory()) { v.addAll(recurseSubdirectories(f[i].listFiles(),exts)); } else { if (exts == null) { System.out.println("Adding " + f[i].getName()); v.add(f[i]); } else { s = ext(f[i]); for(int j = 0; j < exts.length; j++) { if(s.equalsIgnoreCase(exts[j])) { System.out.println("Adding " + f[i].getName()); v.add(f[i]); break; } } } } } return v; } private static void copyFile(File src, File dest) throws IOException { try { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(dest); byte[] buf = new byte[1024]; int count = 0; while((count=fis.read(buf))!=-1) { fos.write(buf, 0, count); } fis.close(); fos.close(); } catch (Exception e) { if (e instanceof IOException) { throw (IOException)e; } else { System.out.println("Unexpected error. Application failure."); e.printStackTrace(); System.exit(-1); } } } /** * Called from the command line: * java FileHeap -s foo bar -d bas -e .ogg .mp3 */ public static void main(String [] args) { File destdir = null; File [] srcdirs = null; String [] exts = null; if (args.length == 0) { System.out.println(usagemessage); return; } if (!(args[0].equals("-s"))) { System.out.println("Improperly formatted arguments in the " + "source list, or \"-s\" missing"); System.out.println(usagemessage); return; } int i; for (i = 0; i < args.length; i++) { if (args[i].equals("-d") && i + 1 < args.length) { destdir = new File(args[i + 1]); srcdirs = new File [i - 1]; int k = 1; for (int j = 0; j < srcdirs.length; j++, k++) { srcdirs[j] = new File(args[k]); } break; } } if (destdir == null || srcdirs == null || srcdirs.length == 0) { System.out.println("Source or Destination missing, or \"-d\" " + "missing"); System.out.println(usagemessage); return; } i += 2; if (i < args.length) { if (!(args[i].equals("-e")) | ++i >= args.length) { System.out.println("Improperly formatted arguments in the " + "extensions list, or missing \"-e\""); System.out.println(usagemessage); return; } exts = new String [args.length - i]; for (int j = 0; i < args.length; j++, i++) { exts[j] = args[i]; } } FileHeap fh = null; try { fh = new FileHeap(srcdirs,destdir,exts); } catch (Exception e) { e.printStackTrace(); System.out.println(e.toString() + "\n"); System.out.println(usagemessage); return; } try { fh.heap(); } catch (IOException e) { System.out.println("Unexpected IO error"); e.printStackTrace(); } } }