/**
* 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();
}
}
}