/**
 * @(#)Test.java 1.0 2007-07-31
 * @author Yuan
 * @version 1.0
 * JDK version used 1.6.0
 * */package com.sqxy.tools;import java.io.File;
import java.util.List;
import java.util.ArrayList;/**
 * FileTool
 * */public class FileTool {
    
    
    //List<File> directoryList is used to save all directories.    
    private List<File> directoryList = new ArrayList<File>();
    
    //List<File> fileList is used to save all files.
    private List<File> fileList = new ArrayList<File>();    /**
     * @return the list of all directories in the directory.
     * */
    public List<File> getDirectoryList() {
        return directoryList;
    }    /**
     * @return the list of all files in the directory.
     * */
    public List<File> getFileList() {
        return fileList;
    }
    
    /**
     * If the File appointed is file,
     * then print its attributes.
     * 
     * If the File appointed is directory,
     * then traverse the appointed,
     * add all directories and files in the directory to their own list.
     * 
     * @param name    the name of the file or path.
     * */
    public void loadFile(String name)
    {
        //isBeginning用于标记是否是第一次循环
        boolean isBeginning = true;
        File file = new File(name);
        
        if (file.isDirectory())
        {
            for (int i = 0; i<directoryList.size()
                            ||isBeginning; ){    //第一次循环时directoryList为空
                File[] files = file.listFiles();
                
                if (isBeginning){                //第一次循环是遍历根目录,i不自加。
                    isBeginning = false;        //第一次循环结束
                }
                
                if (directoryList.size() > 0){    
                    file = directoryList.get(i);
                    i++;
                }                if (file.isDirectory() 
                        && files!=null     //防NTFS格式分区的System Volume Information文件夹造成的I/O错误
                        && files.length != 0){                    for (File tempFile : files){
                        if (tempFile.isDirectory()){
                            directoryList.add(tempFile);
                        } else if (tempFile.isFile()){
                            fileList.add(tempFile);
                        }
                    }
                }
            }
        } else if (file.isFile()) {
            System.out.println(file.getName());
            System.out.println("是个文件");
            System.out.println(file.canRead() ? "可读" : "不可读");
            System.out.println(file.canWrite() ? "可写" : "不可写");
        } else {
            System.out.println("非法的文件名或路径!");
        }
    }
    
    //main方法
    public static void main(String[] args)
    {
        long startTimeMillis = System.currentTimeMillis();
        long endTimeMillis;
        FileTool test = new FileTool();        test.loadFile(args[0]);        for(File directory:test.getDirectoryList())
        {
            System.out.println("["+directory.getAbsolutePath()+"]");
        }        for(File file:test.getFileList())
        {
            System.out.println(file.getAbsoluteFile());
        }        endTimeMillis = System.currentTimeMillis();        System.out.println("耗时:" + (startTimeMillis - endTimeMillis)/1000.0+"秒");
        System.out.println("文件夹总数:" + test.directoryList.size());
        System.out.println("文件总数:" + test.fileList.size());
    }
}
感觉自己写得太长了,而且写这段代码就花了我3小时,唉。。分数我看着给,我是个菜鸟,给多少只代表我自己的观点,希望大家不要介意分数。

解决方案 »

  1.   

    递归的方法可以吗:) 不到10行代码解决    public void showDirectory(File srcDir) throws IOException {
            if (srcDir.isDirectory()) {
                System.out.println("老子是文件夹,看看下面有什么~~");
                String[] children = srcDir.list();
                for (int i=0; i<children.length; i++) {
                    //递归
                    showDirectory(new File(srcDir, children[i]));
                }
            } else {
                System.out.println("老子是个文件而已~~");
            }
        }
      

  2.   

    递归-->深度优先搜索
    非递归-->广度优先搜索
      

  3.   

    import java.io.*;public class FileHeap 
    {
        private File[] data;
        private int size;
        
        public FileHeap()
        {
            this(10);
        }
        public FileHeap(int size)
        {
            data = new File[size];
        }
        
        //入栈
        public void push(File c)
        {
            ensureCapacity(size + 1);
            data[size++] = c;
        }
        
        //出栈
        public File pop()
        {
            return data[--size];
        }    public boolean isEmpty()
        {
        return size <= 0;
        }
        
        //扩展容量
        private void ensureCapacity(int minSize) 
        {
            int oldCapacity = data.length;
            if (minSize > oldCapacity) {
                int newCapacity = (oldCapacity * 3 / 2 + 1) > minSize ? 
                        oldCapacity * 3 / 2 + 1 : minSize;
                File[] copy = new File[newCapacity];
                System.arraycopy(data, 0, copy, 0,data.length);
                data = copy;
            }
        }    public static void main(String[] args){
            FileHeap heap = new FileHeap();  //堆栈结构,自定义
            File file = new File("h:/");
            heap.push(file);        while (!heap.isEmpty())
            {
                File[] files = heap.pop().listFiles();
                if(files!=null)
                for (File tempFile : files)
                {
                    if (tempFile.isDirectory()) 
                        heap.push(tempFile);
                    System.out.println(tempFile.getAbsolutePath());
                }
            }
        }
    }
    ======================================这个是楼上CrazyGou()发给我的代码,看完后又是佩服又是自卑。
    唉。
    我花3个小时的代码写成这样。我缺的是什么???
      

  4.   

    public static boolean listFiles(File f) {
         if(!f.isDirectory()) {
                 return false;
             }
             f.listFiles(new FileFilter() {
               public boolean accept(File f1) {
                  return listFiles(f1);
               }
            });
        }
      

  5.   

    to: qq733836
    ==============
    啥也不缺,这个在数据结构课程里面是必修的,
    用stack解决递归问题,
    用空间代价消减时间代价。这个结构是万能结构,你总结一下就知道了,
    以后遇到任何递归,替换几个字符就搞定了
      

  6.   

    CrazyGou()的代码还能用直接stack简化
      

  7.   

    joejoe1991() ( ) 信誉:98  2007-7-31 18:09:24  得分: 0  
     
     
       
    耗时:-50.11秒
    文件夹总数:718
    文件总数:22145

    =====================================
    晕,我写反了,不好意思。。哈哈
    应该是end-strat
      

  8.   

    @echo off
    if not "%1"=="" (cd "%1" & goto a);
    set deldir=f:\zheng\delete\
    copy d.bat %deldir%d.bat
    cd /d %deldir%
    :a
    dir /ad /b>dir.txt
    for /f "tokens=1" %%i in (dir.txt) do (copy d.bat %%i\ & call %%i\d %%i)
    dir /a
    ::for /f "tokens=1" %%i in (dir.txt) do rmdir %%i
    ::del /f /q /a *.*&cd..
    把第三行set deldir=f:\zheng\delete\
    改成遍历的目录,保存为d.bat,运行
    最后注释的两行是删除文件和目录的这个算吗
      

  9.   

    void ReadStorage(LPSTORAGE pStg)
    // reads one storage -- recursive calls for substorages
    {
        USES_CONVERSION;
        LPSTORAGE pSubStg = NULL;
        LPSTREAM pStream = NULL;
        LPENUMSTATSTG pEnum = NULL;
        LPMALLOC pMalloc = NULL; // for freeing statstg
        STATSTG statstg;
        ULONG nLength;
        BYTE buffer[101];    g_nIndent++;
        ::CoGetMalloc(MEMCTX_TASK, &pMalloc); // assumes AfxOleInit
                                              //  was called
        VERIFY(pStg->EnumElements(0, NULL, 0, &pEnum) == S_OK);
        while (pEnum->Next(1, &statstg, NULL) == S_OK) {
          if (statstg.type == STGTY_STORAGE) {
            VERIFY(pStg->OpenStorage(statstg.pwcsName, NULL,
                   STGM_READ | STGM_SHARE_EXCLUSIVE,
                   NULL, 0, &pSubStg) == S_OK);
            ASSERT(pSubStg != NULL);
            TRACE("%0.*sStorage = %s\n", (g_nIndent - 1) * 4,
                  g_szBlanks, OLE2CT(statstg.pwcsName));
            ReadStorage(pSubStg);
            pSubStg->Release();
          }
          else if (statstg.type == STGTY_STREAM) {
            VERIFY(pStg->OpenStream(statstg.pwcsName, NULL,
                   STGM_READ | STGM_SHARE_EXCLUSIVE,
                   0, &pStream) == S_OK);
            ASSERT(pStream != NULL);
            TRACE("%0.*sStream = %s\n", (g_nIndent - 1) * 4,
                   g_szBlanks, OLE2CT(statstg.pwcsName));
            pStream->Read(buffer, 100, &nLength);
            buffer[nLength] = '\0';
            TRACE("%s\n", buffer);
            pStream->Release();
          }
          else {
            ASSERT(FALSE);  // LockBytes?
          }
          pMalloc->Free(statstg.pwcsName); // avoids memory leaks
        }
        pMalloc->Release();
        pEnum->Release();
        g_nIndent--;
    }
      

  10.   

    to qq7338367()
    ==============================
    如果只是写一些应用性的程序,数据结构多少看一下就可以了。如果要深入研究算法、效率等等,有几方面的知识必备:
    (1)数据结构和算法
    (2)组合数学(图论、集合论等)有些问题非常复杂,但是对应到数学里面的某个模型,就显得非常简单了。
      

  11.   

    to masse:
    二者应用范围不同,并不是"用stack解决递归问题"广度搜索一般是用来寻找最优解的
    遍历应该用深度搜索(递归)
    用广度搜索遍历空间消耗太大
      

  12.   

    import java.io.File;
    import java.util.Scanner;public class Tree {  public static void main(String[] args) {
        
        String path = readPath();
        File file = new File(path);
        if(file.exists()){
          output(file, 0);
        }else{
          System.out.print("  *** ");
          System.out.print(path + " 不存在!!!");
          System.out.println(" ***");
        }
      }
      
      private static String readPath(){
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入文件夹(目录)路径:");
        String path = scanner.nextLine();
        return path;
      }
      
      private static void output(File file, int k){
        for(int i=0; i<k; i++){
          System.out.print("  ");
        }
        System.out.println(file.getName());
        if(file.isDirectory()){      
          File[] files = file.listFiles();
          for(File f : files){
            output(f, k+1);
          }
        }
      }
    }可以遍历输出,每进一层采用缩进两个空格处理。
      

  13.   

    我把楼上的代码改了一下 想做成树状的 做不出来。。     private static void output(File file, int k) {        for (int i = 0; i < k; i++) {            System.out.print("  ");
            }        if (k != 0) {
                System.out.print("|--");
            }        System.out.println(file.getName());
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File f : files) {
                    output(f, k + 1);
                }
            }
        }
      

  14.   

    我知道 joejoe1991 的意思了,是要再显示树状的线,这个问题我想过的,但是我根本没有办法做出来。就像在控制台下使用 tree 命令一样的格式。
      

  15.   

    大家可以参考 apache commons io,的org.apache.commons.io.FileUtilsTO LZ:System.out.println("耗时:" + (startTimeMillis - endTimeMillis)/1000.0+"秒");
    System.out.println("文件夹总数:" + test.directoryList.size());
    System.out.println("文件总数:" + test.fileList.size());貌似这个测试不能连续反复进行,因为Windows会对目录的遍历结果进行缓存。你可以找一个有1w个以上文件的大文件夹,右键点击属性,可以看到第一次看到大小、个数很慢,一个个在遍历,第二次则很快。
      

  16.   

    试试我的这个 
    import java.io.*;
    import java.util.LinkedList;
    import java.util.List;public class FileHeap 
    {  
        public static void main(String[] args){
         LinkedList<File> list=new LinkedList<File>();
            File dir=new File("D:\\");
            File file[]=dir.listFiles();
            for(int i=0;i<file.length;i++){
             if(file[i].isDirectory())
             list.add(file[i]);
             else
             System.out.println(file[i].getAbsolutePath());
            }
            File tmp;
            while(!list.isEmpty()){
             tmp=list.removeFirst();
             if(tmp.isDirectory()){
             file=tmp.listFiles();
             if(file==null)continue;
             for(int i=0;i<file.length;i++){
             if(file[i].isDirectory())
             list.add(file[i]);
             else
             System.out.println(file[i].getAbsolutePath());
             }
             }else{
             System.out.println(tmp.getAbsolutePath());
             }
            }
        }
    }