package ecologylab.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; import java.util.Date; import ecologylab.generic.Debug; import ecologylab.generic.StringTools; /** * A set of lovely convenience methods for doing operations on local files. */ public class Files extends Debug { // to update, add entry here, and below in deriveLang() public static final int NONE = -1; public static final int UNKNOWN = -1024; public static final int HTML = 0; public static final int JAVA = 1; public static final int JAVASCRIPT = 2; public static final int ASP = 3; public static final int CSS = 4; public static final int EXE = 5; public File outFile, inFile; public BufferedReader fileReader; public BufferedWriter fileWriter; String tempFileName; static String readErrorString = "Error reading from file "; static String writeErrorString = "Error writing to file "; public static final char sep = File.separatorChar; static public final String indent = "\t"; public Files() { } public Files(String inFileName) { setInFile(inFileName); } public void setInFile(String inFileName) { inFile = newFile(inFileName); } /** * Create a new File object. * * More robust than just calling the File constructor, cause it converts all slashes to the * direction native for the platform. */ public static File newFile(String inFileName) { return newFile((File) null, inFileName); } /** * Create a new File object. * * More robust than just calling the File constructor, cause it converts all slashes to the * direction native for the platform. */ public static File newFile(String contextName, String inFileName) { return newFile(newFile(contextName), inFileName); } /** * Create a new File object. * * More robust than just calling the File constructor, cause it converts all slashes to the * direction native for the platform. */ public static File newFile(File context, String inFileName) { // one of the replaces should do something; // and the other should do nothing. String fixedFileName = inFileName.replace('/', sep).replace('\\', sep); File one = new File(fixedFileName); if (context == null) return one; if (one.isAbsolute() || (context == null)) { // hack gnarly windows path shit // (drives & backslashes are a plague on all programmers) if (fixedFileName.length() > 1 && fixedFileName.charAt(1) != ':') { String contextName = context.getPath(); if (contextName.charAt(1) == ':') { String fixedFixed = contextName.substring(0, 2) + fixedFileName; return new File(fixedFixed); } } return one; } // else // Debug.println("newFile: (0)="+fixedFileName.charAt(0) + " (1)"+ // fixedFileName.charAt(0)); // if ((fixedFileName.charAt(1) == ':') || (fixedFileName.charAt(0) == sep)) // return new File(fixedFileName); // else return new File(context, fixedFileName); } public void close() { closeReader(); closeWriter(); } public boolean closeReader() { return closeReader(fileReader); } public static boolean closeReader(BufferedReader reader) { boolean ok = true; if (reader != null) try { reader.close(); } catch (IOException ioe) { ok = false; } return ok; } public boolean closeWriter() { return closeWriter(fileWriter); } public static boolean closeWriter(BufferedWriter writer) { boolean ok = true; try { writer.close(); } catch (IOException outE) { ok = false; } return ok; } public static BufferedReader openReader(String fileName) { return openReader(newFile(fileName)); } // public static BufferedReader openWebReader(String webAddr) // { // /* get ParsedURL from url string. */ // ParsedURL purl = EnvironmentGeneric.getRelativeOrAbsolute(webAddr, ""); // return openReader(purl.url()); // } public static BufferedReader openReader(File file) { boolean ok = file.canRead(); if (!ok) { println("Can't read file " + file.getAbsolutePath()); return null; } println(3, "Input file: " + file); FileReader fileReader = null; try { fileReader = new FileReader(file); return openReader(fileReader); } catch (FileNotFoundException e) { println("Can't find file " + file.getAbsolutePath()); return null; } } public static InputStream openStream(URL url) { InputStream inStream = null; try { URLConnection connection = url.openConnection(); inStream = connection.getInputStream(); } catch (FileNotFoundException e) { println("Can't open because FileNotFoundException: " + url); } catch (IOException e) { println("Can't open because IOException: " + url); } catch (Exception e) // catch all exceptions, including security { println("Can't open " + url); e.printStackTrace(); } return inStream; } public static BufferedReader openReader(URL url) { InputStream inStream = openStream(url); return (inStream == null) ? null : openReader(inStream); } public static BufferedReader openReader(InputStream inStream) { return openReader(new InputStreamReader(inStream)); } public static BufferedReader openReader(InputStreamReader inputStreamReader) { return new BufferedReader(inputStreamReader); } public boolean openRead(File inputFile) { inFile = inputFile; return openReader(); } public boolean openRead(String inFileName) { setInFile(inFileName); return openReader(); } public static String getTempFileName(String name) { Date myZone = new Date(); return sep + "temp" + sep + name + myZone.getTime(); } public boolean openReader() { fileReader = openReader(inFile); return (fileReader != null); } public String getDir(String fullPath) { int index = fullPath.lastIndexOf(File.separator); if (index == -1) return ""; return fullPath.substring(0, index); } public boolean openWrite(String outFileName) { return openWrite(newFile(outFileName)); } public boolean openWrite(File outDir, String outFileName) { return openWrite(newFile(outDir, outFileName)); } public boolean openWrite(File oFile) { outFile = oFile; BufferedWriter writer = openWriter(oFile); boolean ok = (writer != null); if (ok) fileWriter = writer; return ok; } public static BufferedWriter openWriter(String oFileName) { return openWriter(newFile(oFileName)); } public static BufferedWriter openWriter(String oFileName, boolean append) { return openWriter(newFile(oFileName), 1, append); } public static BufferedWriter openWriter(File oFile, boolean append) { return openWriter(oFile, 1, append); } public static BufferedWriter openWriter(File oFile) { return openWriter(oFile, 1); } /** * Make any directories necesary for the file to be written. */ public static boolean makePath(File oFile) { String oFileDirName = oFile.getParent(); File oFileDir = newFile(oFileDirName); boolean result = !oFileDir.equals(""); if (result) // if ok, continue { result = oFileDir.exists(); if (!result) // if exists, no more work to do { println("\t"); println(oFileDir + " "); result = oFileDir.mkdirs(); if (!result) Debug.println("[Making directories for you: failed.]"); } } else Debug.println("Can't write to " + oFile.getAbsolutePath()); return result; } public static BufferedWriter openWriter(File oFile, int debugLevel) { if (oFile == null) return null; BufferedWriter writer = null; String oFileFullPath = oFile.getAbsolutePath(); println("Files.openWriter(" + oFileFullPath); // if (makePath(oFile)) // maybe create directories along the path try { writer = new BufferedWriter(new FileWriter(oFile)); println("\tOutput file: "); println(indent + indent + oFileFullPath); } catch (IOException e) { Debug.println(writeErrorMsg(e, oFileFullPath)); } return writer; } public static BufferedWriter openWriter(File oFile, int debugLevel, boolean append) { if (oFile == null) return null; BufferedWriter writer = null; String oFileFullPath = oFile.getAbsolutePath(); println("Files.openWriter(" + oFileFullPath); // if (makePath(oFile)) // maybe create directories along the path try { writer = new BufferedWriter(new FileWriter(oFile, append)); println("\tOutput file: "); println(indent + indent + oFileFullPath); } catch (IOException e) { Debug.println(writeErrorMsg(e, oFileFullPath)); } return writer; } public static FileInputStream openInStream(File inFile) { FileInputStream stream = null; try { stream = new FileInputStream(inFile); } catch (Exception e) { Debug.println("Can't open input stream from " + inFile + " " + e); } return stream; } public static BufferedOutputStream openOutStream(File oFile) { BufferedOutputStream outStream = null; String oFileFullPath = oFile.getAbsolutePath(); if (makePath(oFile)) // maybe create directories along the path try { outStream = new BufferedOutputStream(new FileOutputStream(oFile)); println(3, "Output file: "); println(3, indent + oFileFullPath); } catch (IOException e) { Debug.println(writeErrorMsg(e, oFileFullPath)); } return outStream; } public String readLine() { return readLine(fileReader); } public static String readLine(BufferedReader reader) { String aLine = " "; try { aLine = reader.readLine(); } catch (IOException e) { Debug.println(readErrorString + reader); } return aLine; } public boolean write(String toWrite) { return write(fileWriter, toWrite); } public static boolean write(BufferedWriter writer, String toWrite) { if ((toWrite == null) || (toWrite.equals(""))) return true; boolean ok = true; try { writer.write(toWrite); } catch (IOException e) { ok = false; Debug.println(writeErrorMsg(e, writer)); } return ok; } // write a line of output public boolean writeLine(String toWrite) { // Env.println("really writing a line"); return writeLine(fileWriter, toWrite); } public static boolean writeLine(BufferedWriter writer, String... toWrite) { if (toWrite == null) return true; boolean ok = true; try { for (String sToWrite : toWrite) writer.write(sToWrite); writer.newLine(); } catch (IOException e) { ok = false; // dont use Debug, to avoid infinite loops!!! System.err.println(writeErrorMsg(e, writer)); } return ok; } public static boolean flush(BufferedWriter writer) { boolean result = false; try { writer.flush(); result = true; } catch (IOException e) { } return result; } public void rename(String finalName) { File newFile = newFile(finalName); outFile.renameTo(newFile); // Env.println("All done!!!!!"); } public boolean insertFile(String fileToInsert) { return insertFile(fileWriter, fileToInsert); } // TODO this is also old dead code public static void copyTraceFile(File outputFile) { final String TRACE_PATH = System.getProperty("deployment.user.logdir") + "/plugin" + StringTools.remove(System.getProperty("java.version"), '_') + ".trace"; BufferedWriter writer; BufferedReader reader; reader = openReader(TRACE_PATH); writer = openWriter(outputFile); String oneLine = readLine(reader); while (oneLine != null) { writeLine(writer, oneLine); oneLine = readLine(reader); } closeReader(reader); closeWriter(writer); } public static boolean insertFile(BufferedWriter writer, String fileToInsert) { BufferedReader reader = openReader(fileToInsert); boolean ok = (reader != null); if (ok) { String line; for (line = readLine(reader); line != null; line = readLine(reader)) { // Env.println("into " + reader + " inserting: " + line); writeLine(writer, line); } } try { reader.close(); } catch (IOException e) { ok = false; } return ok; } public static boolean isDir(File file) { if (file.isDirectory()) return true; // this is a bit of a hack -- it assumes files w suffixes String lastPart = file.getName(); return lastPart.indexOf(".") < 0; } // ????? i dunno where this was being used (CMDOC???) // write a line of output // public boolean writeLine(String toWrite) // { // return writeLine(toWrite, false); // } public static boolean copy(File from, File to) { if (!from.exists()) { println("I can't copy because<br>\n" + from.toString() + " doesn't exist."); println(""); return false; } println(2, "Copy:"); println(2, indent + from); println(2, indent + to); File dir; if (isDir(to)) { dir = to; to = newFile(to, from.getName()); } else dir = newFile(to.getParent()); if (!dir.exists()) dir.mkdirs(); BufferedReader input = null; BufferedWriter output = null; boolean ok = true; try { if (to.exists()) to.delete(); input = new BufferedReader(new FileReader(from)); output = new BufferedWriter(new FileWriter(to)); // output = new FileOutputStream(to); } catch (IOException e) { Debug.println("Files.copy error opening streams: " + e); ok = false; } if (ok) { char buf[] = new char[32768]; // 32 K int count = 0; try { ok = false; while ((count = input.read(buf)) >= 0) { output.write(buf, 0, count); } ok = true; } catch (IOException e) { File errorFile = ok ? to : from; String operation = ok ? "writing" : "reading"; Debug.println("I/O error during copying, while " + operation + " " + errorFile.getAbsolutePath()); ok = false; } try { ok = false; input.close(); ok = true; output.close(); } catch (IOException e) { File errorFile = ok ? to : from; Debug.println("I/O error during copying, while closing " + errorFile.getAbsolutePath()); ok = false; } } return ok; } public static String relativePath(File parent, File child) { String parentPath = parent.getAbsolutePath(); String childPath = child.getAbsolutePath(); return relativePath(parentPath, childPath); } public static String relativePath(File parent, String childPath) { String parentPath = parent.getAbsolutePath(); return relativePath(parentPath, childPath); } public static String relativePath(String parentPath, String childPath) { println(3, "Relative Path:"); println(3, indent + parentPath); println(3, indent + childPath); if (parentPath.equals(childPath)) return ""; if (childPath.indexOf(parentPath) > -1) { println(3, indent + childPath.substring(parentPath.length() + 1)); return childPath.substring(parentPath.length() + 1); } else return null; } public static String getBeforeExtension(File file) { return getBeforeExtension(file.getName()); } public static String getBeforeExtension(String fName) { String before = ""; int dot = fName.lastIndexOf("."); if (dot >= 0) before = fName.substring(0, dot); return before; } public static String getExtension(File file) { return getExtension(file.getName()); } public static String getExtension(String fName) { String ext = null; int dot = fName.lastIndexOf("."); if ((dot >= 0) && (dot < fName.length() - 1)) ext = fName.substring(dot + 1); return ext; } public static int deriveLang(String fName) { int lang; String ext = getExtension(fName); println(4, "deriveLang got extension='" + ext + "'"); if (ext == null) lang = HTML; { ext = ext.toLowerCase(); if (ext.equals("html") || ext.equals("htm")) lang = HTML; else if (ext.equals("java")) lang = JAVA; else if (ext.equals("js")) lang = JAVASCRIPT; else if (ext.equals("asp")) lang = ASP; else if (ext.equals("css")) lang = CSS; else if (ext.equals("exe")) lang = EXE; else lang = UNKNOWN; } return lang; } public static String unix(File f) { return f.getAbsolutePath().replace(sep, '/'); } public static String unix(String s) { return s.replace(sep, '/'); } public static boolean contains(String fileName, String s) { return contains(fileName, s); } public static boolean contains(File f, String s) { BufferedReader reader = openReader(f); for (String line = Files.readLine(reader); line != null; line = Files.readLine(reader)) { if (line.indexOf(s) > -1) return true; } return false; } public static File removeExtension(File f) { return (f.getName().indexOf('.') == -1) ? f : removeExtension(f.getPath()); } public static File removeExtension(String path) { File result; int lastDot = path.lastIndexOf('.'); int lastSlash = path.lastIndexOf(sep); if (lastDot > lastSlash) { path = path.substring(0, lastDot); result = new File(path); } else result = new File(path); return result; } // public static void main(String[] s) // { // // println(removeExtension(new File("c:/temp/foo.xml")).toString()); // BufferedReader reader = openWebReader(s[0]); // String thatLine = null; // while ((thatLine = Files.readLine(reader)) != null) // { // println("read from URL " + thatLine); // } // closeReader(reader); // } public static void main2(String[] args) throws Exception { URL yahoo = new URL("http://www.yahoo.com/"); BufferedReader in = new BufferedReader(new InputStreamReader(yahoo.openStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); } public static String writeErrorMsg(Throwable e, Object o) { return writeErrorMsg(e, o.toString()); } public static String writeErrorMsg(Throwable e, File f) { return writeErrorMsg(e, f.getAbsolutePath()); } public static String writeErrorMsg(Throwable e, String path) { return "Error [" + e.getMessage() + "] writing to file " + path; } /** * removes all the files in a given directory * * @param dir * the dir to be cleared */ public static void clearDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { new File(dir, children[i]).delete(); } } } /** * copies all the files of a particular type from the src dir to the dest dir * * @param srcDir * source dir * @param dstDir * destination dir * @param fileType * type of the file, for example jpg for jpeg files if fileType is null, all the files * are copied */ public static void copyFiles(File srcDir, File dstDir, String fileType) { if (srcDir.isDirectory()) { String[] children = srcDir.list(); for (int i = 0; i < children.length; i++) { if (fileType != null) { // copy only if the file is of the specified type if (children[i].endsWith(fileType)) copyFile(new File(srcDir, children[i]), new File(dstDir, children[i])); } else { copyFile(new File(srcDir, children[i]), new File(dstDir, children[i])); } } } } /** * Copy a file -- binary or character data. * * @param srcFile * @param dstFile */ public static void copyFile(File srcFile, File dstFile) { try { // Create channel on the source FileChannel srcChannel = new FileInputStream(srcFile).getChannel(); // Create channel on the destination FileChannel dstChannel = new FileOutputStream(dstFile).getChannel(); // Copy file contents from source to destination dstChannel.transferFrom(srcChannel, 0, srcChannel.size()); // Close the channels srcChannel.close(); dstChannel.close(); } catch (IOException e) { e.printStackTrace(); } } /** * Get the XML files in the directory. * * @param directoryPath * The file system parth for the directory. * * @return Array of File objects that constitute an ls *.xml for the directory. */ public static File[] getXMLFiles(String directoryPath) { return getXMLFiles(new File(directoryPath)); } public static File[] getXMLFilesNonRecursive(String directoryPath) { return getXMLFilesNonRecursive(new File(directoryPath)); } /** * Get the XML files in the directory. * * @param directory * File object for the directory * * @return Array of File objects that constitute an ls *.xml for the directory. */ public static File[] getXMLFiles(File directory) { java.io.FileFilter XMLfilter = XMLFileFilter.get(); return directory.isDirectory() ? directory.listFiles(XMLfilter) : null; } /** * Get XML files only in this directory * * @param directory * @return */ public static File[] getXMLFilesNonRecursive(File directory) { java.io.FileFilter XMLfilter = XMLFileNonRecursiveFilter.get(); return directory.isDirectory() ? directory.listFiles(XMLfilter) : null; } /** * Recursively delete a directory on the file system. We must recursively delete it since java * requires that the directory be empty before deletion. * * @param targetDir * The target directory to delete. * @return true if successful, false otherwise. */ public static boolean deleteDirectory(File targetDir) { boolean succeeded = true; if (targetDir.exists()) { File[] dirFiles = targetDir.listFiles(); for (int i = 0; i < dirFiles.length; i++) { File dirFile = dirFiles[i]; if (dirFile.isDirectory()) { succeeded = succeeded && deleteDirectory(dirFile); } else { dirFile.delete(); } } succeeded = succeeded && targetDir.delete(); } return succeeded; } public static String getFilenameMinusExtension(File file) { String pathString = file.getAbsolutePath(); return pathString.substring(pathString.lastIndexOf(sep) + 1, pathString.lastIndexOf('.')); } public static boolean isZipFile(File file) throws IOException { BufferedInputStream fin = new BufferedInputStream(new FileInputStream(file)); boolean isZipStream = StreamUtils.isZipStream(fin); fin.close(); return isZipStream; } public static File findFirstExistingAncestor(File file) { if (file != null) { File parent = file.getParentFile(); if (parent != null && parent.exists()) return parent; return findFirstExistingAncestor(parent); } return null; } /** * Given two absolute paths, find the deepest common ancestor between them. * * @param file1 * @param file2 * @return */ public static String findMostCommonAncestor(String file1, String file2) { if (file1 != null && file2 != null) { if (file1.length() == 0 || file2.length() == 0) return ""; int file1FirstDir = file1.indexOf(File.separatorChar); int file2FirstDir = file2.indexOf(File.separatorChar); if (file1FirstDir == -1 || file2FirstDir == -1) return ""; String substring = file1.substring(0, file1FirstDir + 1); if (substring.equals(file2.substring(0, file2FirstDir + 1))) { return substring + findMostCommonAncestor( file1.substring(file1FirstDir + 1), file2.substring(file2FirstDir + 1)); } return ""; } return null; } } class XMLFileNonRecursiveFilter implements java.io.FileFilter { static XMLFileNonRecursiveFilter singleton; static XMLFileNonRecursiveFilter get() { XMLFileNonRecursiveFilter result = singleton; if (result == null) { result = new XMLFileNonRecursiveFilter(); singleton = result; } return result; } public XMLFileNonRecursiveFilter() { } @Override public boolean accept(File file) { String name = file.getName().toLowerCase(); return name.endsWith(".xml"); } }// end class HTMLFileFilter