This little program has
saved me a great deal of time over the
years. It reads a directory containing a large number of files,
harking back from a time when I kept all my demonstration Java
programs in a fairly flat directory structure.
MkIndex
, shown in Example 17-7,
produces a better-formatted listing than the default directory that
web servers generate. For one thing, it includes an alphabet
navigator, which lets you jump directly to the section of files whose
names begin with a certain letter, saving a lot of scrolling time or
iterations with the browser’s find menu. This program uses a
File
object (see Section 10.2) to
list the files, and another to decide which are files and which are
directories. It also uses Collections.sort
(see
Section 7.9) to sort the names alphabetically before
generating the output. It writes its output to the file
index.html
in the current directory, even if an
alternate directory argument is given. This is the default filename
for most standard web servers; if your web server uses something
different, of course, you can rename the
file.
Example 17-7. MkIndex.java
/** MkIndex -- make a static index.html for a Java Source directory */ public class MkIndex { /** The output file that we create */ public static final String OUTPUTFILE = "index-byname.html"; /** The string for TITLE and H1 */ public static final String TITLE = "Ian Darwin's Java Cookbook: Source Code: By Name"; /** The main output stream */ PrintWriter out; /** The background color for the page */ public static final String BGCOLOR="#33ee33"; /** The File object, for directory listing. */ File dirFile; /** Make an index */ public static void main(String[] args) throws IOException { MkIndex mi = new MkIndex( ); String inDir = args.length > 0 ? args[0] : "."; mi.open(inDir, OUTPUTFILE); // open files mi.BEGIN( ); // print HTML header mi.process( ); // do bulk of work mi.END( ); // print trailer. mi.close( ); // close files } void open(String dir, String outFile) { dirFile = new File(dir); try { out = new PrintWriter(new FileWriter(outFile)); } catch (IOException e) { System.err.println(e); } } /** Write the HTML headers */ void BEGIN( ) throws IOException { println("<HTML>"); println("<HEAD>"); println(" <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">"); println(" <META NAME="GENERATOR" CONTENT="Java MkIndex">"); println(" <title>" + TITLE + "</title>"); println("</HEAD>"); println("<body bgcolor="" + BGCOLOR + "">"); println("<h1>" + TITLE + "</h1>"); if (new File("about.html").exists( )) { FileIO.copyFile("about.html", out, false); } else { println("<P>The following files are online."); println("Some of these files are still experimental!</P>"); println("<P>Most of these files are Java source code."); println("If you load an HTML file from here, the applets will not run!"); println("HTML files must be saved to disk and the applets compiled,"); println("before you can run them!"); } println("<P>All files are Copyright ©: All rights reserved."); println("See the accompanying <A HREF="legal-notice.txt ">Legal Notice</A> for conditions of use."); println("May be used by readers of my Java Cookbook for educational purposes,"); println("and for commercial use if certain conditions are met."); println("</P>"); println("<HR>"); } /** Array of letters that exist. Should * fold case here so don't get f and F as distinct entries! * This only works for ASCII characters (8-bit chars). */ boolean[] exists = new boolean[255]; /** Vector for temporary storage, and sorting */ ArrayList vec = new ArrayList( ); /** Do the bulk of the work */ void process( ) throws IOException { System.out.println("Start PASS ONE -- from directory to Vector..."); String[] fl = dirFile.list( ); for (int i=0; i<fl.length; i++) { String fn = fl[i]; if (fn.startsWith("index")) { // we'll have no self-reference here! System.err.println("Ignoring " + fn); continue; } else if (fn.endsWith(".bak")) { // delete .bak files System.err.println("DELETING " + fn); new File(fn).delete( ); continue; } else if (fn.equals("CVS")) { // Ignore CVS subdirectories continue; // don't mention it } else if (fn.charAt(0) == '.') { // UNIX dot-file continue; } else if (fn.endsWith(".class")) { // nag about .class files System.err.println("Ignoring " + fn); continue; } else if (new File(fn).isDirectory( )) { vec.add(fn + "/"); } else vec.add(fn); exists[fn.charAt(0)] = true; // only after chances to continue } System.out.println("Writing the Alphabet Navigator..."); for (char c = 'A'; c<='Z'; c++) if (exists[c]) print("<A HREF="#" + c + "">" + c + "</A> "); // ... (and the beginning of the HTML Unordered List...) println("<UL>"); System.out.println("Sorting the Vector..."); Collections.sort(vec, String.CASE_INSENSITIVE_ORDER); System.out.println("Start PASS TWO -- from Vector to " + OUTPUTFILE + "..."); String fn; Iterator it = vec.iterator( ); while (it.hasNext( )) { fn = (String)it.next( ); // Need to make a link into this directory. // IF there is a descr.txt file, use it for the text // of the link, otherwise, use the directory name. // But, if there is an index.html or index.html file, // make the link to that file, else to the directory itself. if (fn.endsWith("/")) { // directory String descr = null; if (new File(fn + "descr.txt").exists( )) { descr = com.darwinsys.util.FileIO.readLine(fn + "descr.txt"); }; if (new File(fn + "index.html").exists( )) mkDirLink(fn+"index.html", descr!=null?descr:fn); else if (new File(fn + "index.htm").exists( )) mkDirLink(fn+"index.htm", descr!=null?descr:fn); else mkLink(fn, descr!=null?descr:fn + " -- Directory"); } else // file mkLink(fn, fn); } System.out.println("*** process - ALL DONE***"); } /** Keep track of each letter for #links */ boolean done[] = new boolean[255]; void mkLink(String href, String descrip) { print("<LI>"); char c = href.charAt(0); if (!done[c]) { print("<A NAME="" + c + "">"); done[c] = true; } println("<A HREF="" + href + "">" + descrip + "</A>"); } void mkDirLink(String index, String dir) { // XXX Open the index and look for TITLE lines! mkLink(index, dir + " -- Directory"); } /** Write the trailers and a signature */ void END( ) { System.out.println("Finishing the HTML"); println("</UL>"); flush( ); println("<P>This file generated by "); print("<A HREF="MkIndex.java">MkIndex</A>, a Java program, at "); println(new Date().toString( )); println("</P>"); println("</BODY>"); println("</HTML>"); } /** Close open files */ void close( ) { System.out.println("Closing output files..."); if (out != null) out.close( ); } /** Convenience routine for out.print */ void print(String s) { out.print(s); } /** Convenience routine for out.println */ void println(String s) { out.println(s); } /** Convenience for out.flush( ); */ void flush( ) { out.flush( ); } }
3.145.70.170