Changeset 7121


Ignore:
Timestamp:
2004-03-26T15:26:24+12:00 (20 years ago)
Author:
mdewsnip
Message:

A much improved method for sorting file nodes into alphabetical order, with directories coming first. The old version was very very slow on Windows 95 and 98 computers with a large number of files (>3000) in the directory; this version is still slow, but a great deal better than before.

Location:
trunk/gli/src/org/greenstone/gatherer
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/file/FileNode.java

    r7099 r7121  
    3636
    3737    public FileNode(File file) {
    38     ///atherer.println("New FileNode(" + file.getAbsolutePath() + ")");
     38    // System.err.println("New FileNode(" + file.getAbsolutePath() + ")");
    3939    this.file = file;
    4040    }
     
    306306        File[] files = file.listFiles();
    307307        if(files != null && files.length > 0) {
    308             ArrayTools tools = new ArrayTools();
    309308            // Sort the remaining files.
    310             tools.sort(files, true);
     309            System.err.println("Number of files to sort: " + files.length);
     310            ArrayTools.sort(files);
     311            System.err.println("Files sorted.");
    311312            // Now add them to children.
    312313            raw_children = new ArrayList();
     
    316317            raw_children.add(child);
    317318            }
     319
    318320            // Apply the filters set in the model.
    319321            //if(model != null) {
    320322            FileFilter[] filters = model.getFilters();
    321323            for(int i = 0; filters != null && i < filters.length; i++) {
    322             files = tools.filter(files, filters[i].filter, filters[i].exclude);
     324            files = ArrayTools.filter(files, filters[i].filter, filters[i].exclude);
    323325            }
    324326            //}
    325327
    326             // Finally remove any files whose canonical path do not match their absolute one (ie symbolic links). We only do this test under linux, because under windows there is no such thing as a symbolic link, and instead we suffer difficulties with the 16bit truncated file paths not being the same as the canonical ones (i.e Program Files => Progra~1).
    327             /* This test to eliminate infinite recursions causes more problems than it solves
    328             if(!Utility.isWindows()) {
    329             for(int k = files.length; k != 0; k--) {
    330                 try {
    331                 if(!files[k-1].getAbsolutePath().equals(files[k-1].getCanonicalPath())) {
    332                     ///ystem.err.println("For file: " + files[k-1].getName());
    333                     ///ystem.err.println("Absolute Path:  " + files[k-1].getAbsolutePath());
    334                     ///ystem.err.println("Canonical Path: " + files[k-1].getCanonicalPath());
    335                     files = ArrayTools.remove(files, (k-1));
    336                 }
    337                 }
    338                 catch (IOException exception) {
    339                 ///atherer.printStackTrace(exception);
    340                 }
    341             }
    342             }
    343             */
    344328            // Now add them to children.
    345329            for(int i = 0; i < files.length; i++) {
  • trunk/gli/src/org/greenstone/gatherer/util/ArrayTools.java

    r6770 r7121  
    408408    }
    409409
    410     /** Sorts an array of files. */
    411     static public void sort(File[] files) {
    412     sort(files, false);
    413     }
    414 
    415     /** Sorts an array of files. Can also to instructed to list directories first. Case insensitive.
    416      * @param files The File[] to be sorted.
    417      * @param directories_first true if you want to directories to be listed first.
    418      */
    419     static public void sort(File[] files, boolean directories_first) {
    420     if(files != null && files.length > 1) {
    421         FileComparator comparator = new FileComparator(directories_first);
    422         Arrays.sort(files, comparator);
    423     }         
    424     }
     410
     411    /** Sorts an array of files, putting non-files first. Case insensitive.
     412     * @param files_to_sort The File[] to be sorted.
     413     */
     414    static public void sort(File[] files_to_sort)
     415    {
     416    // Return if there is nothing to sort
     417    if (files_to_sort == null || files_to_sort.length <= 1) {
     418        return;
     419    }
     420
     421    FileSystemView fileSystemView = FileSystemView.getFileSystemView();
     422    FileComparator comparator = new FileComparator();
     423
     424    // Separate the file system roots and directories from the files, and sort separately
     425    ArrayList files_list = new ArrayList((files_to_sort.length * 3) / 4);
     426    ArrayList non_files_list = new ArrayList((files_to_sort.length) / 4);
     427    for (int i = 0; i < files_to_sort.length; i++) {
     428        File file = files_to_sort[i];
     429
     430        // File is a system root
     431        if (fileSystemView.isFileSystemRoot(file)) {
     432        non_files_list.add(file);
     433        }
     434        // File is a directory
     435        else if (file.isDirectory()) {
     436        non_files_list.add(file);
     437        }
     438        // File is an actual file
     439        else {
     440        files_list.add(file);
     441        }
     442    }
     443    System.err.println("Number of files: " + files_list.size());
     444    System.err.println("Number of non-files: " + non_files_list.size());
     445
     446    Object[] files = files_list.toArray();
     447    Object[] non_files = non_files_list.toArray();
     448
     449    // Sort files
     450    Arrays.sort(files, comparator);
     451
     452    // Sort non-files
     453    Arrays.sort(non_files, comparator);
     454
     455    // Merge the results, putting non-files before files
     456    int j = 0;
     457    for (int i = 0; i < non_files.length; i++) {
     458        files_to_sort[j++] = (File) non_files[i];
     459    }
     460    for (int i = 0; i < files.length; i++) {
     461        files_to_sort[j++] = (File) files[i];
     462    }
     463    }
     464
    425465
    426466    /** Comparator used to order files. */
    427467    static private class FileComparator
    428468    implements Comparator {
    429     private boolean directories_first = false;
    430 
    431     public FileComparator(boolean directories_first) {
    432         this.directories_first = directories_first;
    433     }
     469
    434470    /** Compare two files in terms of ordering of their paths.
    435471     * @param o1 The <strong>Object</strong> that represents the first file.
    436472     * @param o2 The other <strong>Object</strong>, also a file.
    437      * @return An <i>int</i> which is <1, 0 or >1 if o1 is < o2, = o2 or > o2 respectively.
     473     * @return An <i>int</i> which is <1, 0 or >1 if o1 is <o2, =o2 or >o2 respectively.
    438474     */
    439     public int compare(Object o1, Object o2) {
    440         int result = 0;
     475    public int compare(Object o1, Object o2)
     476    {
    441477        File f1 = (File) o1;
    442         String n1 = f1.getName().toLowerCase();
    443478        File f2 = (File) o2;
    444         String n2 = f2.getName().toLowerCase();
    445                 // Special checks for system roots as these include removable media drives and thus we should never attempt to call isDirectory until the user explicitly attempts to map drive.
    446         boolean f1_system_root = FileSystemView.getFileSystemView().isFileSystemRoot(f1);
    447         boolean f2_system_root = FileSystemView.getFileSystemView().isFileSystemRoot(f2);
    448         if((f1_system_root && f2_system_root) || (!f2_system_root && f1_system_root && f2.isDirectory()) || (!f1_system_root && f1.isDirectory() && f2_system_root) || (f1.isDirectory() && f2.isDirectory()) || (f1.isFile() && f2.isFile())) {
    449         result = n1.compareTo(n2);
    450         }
    451         else if(f1_system_root || f1.isDirectory()) {
    452         result = -1;
    453         }
    454         else {
    455         result = 1;
    456         }
    457         return result;
    458     }
    459     /** Compare two files for equality, in terms of their file paths.
    460      * @param obj The <strong>Object</strong> representing the file we are about to compare ourselves to.
    461      * @return <i>true</i> if we equal the given file, <i>false</i> otherwise.
    462      */
    463     public boolean equals(Object obj) {
    464         return (compare(this, obj) == 0);
     479
     480        return f1.getName().compareToIgnoreCase(f2.getName());
    465481    }
    466482    }
Note: See TracChangeset for help on using the changeset viewer.