美文网首页
JAVA列出磁盘下的所有文件

JAVA列出磁盘下的所有文件

作者: 羊肉馅大包砸 | 来源:发表于2018-01-17 09:44 被阅读0次

开始处理

作为一个停留在JDK1.6版本的老Javaer来说,做这件事第一印象就是File#listFiles方法,来动手。

public static void main(String[] args) {

        System.out.println("系统启动");

        FileTravel travel = new FileTravel(new File("D:/"));

        long start = System.currentTimeMillis();
        travel.travel();
        long end = System.currentTimeMillis();

        System.out.println("耗时:" + ((end - start) / 1000));
    }

public class FileTravel {

    public boolean finish = false;

    public File currentFile = null;

    public int currentForderCnt = 0;

    public int currentFileCnt = 0;

    private File forder = null;

    public FileTravel(File forder) {
        this.forder = forder;
    }

    public void travel() {

        List<FileObject> list = new ArrayList<>();

        travel(forder, list);
    }

    private void travel(File file, List<FileObject> list) {

        Queue<File> queue = new LinkedList<>();
        queue.offer(file);

        File temp = null;
        while (true) {

            temp = queue.poll();
            currentFile = temp;
            currentForderCnt++;

            if (temp == null) {
                break;
            }

            File[] files = temp.listFiles();

            if (files == null) {
                continue;
            }

            for (File subFile : files) {

                if (subFile.isDirectory()) {
                    queue.offer(subFile);
                } else {
                    FileObject obj = new FileObject(subFile.getName(), subFile.length(), subFile.getAbsolutePath());
                    list.add(obj);
                    currentFileCnt++;
                }
            }
        }

        finish = true;
    }
}

我了个叉,竟然需要10多分钟还没有计算完,我竟然还不知道处理到哪里了。那么我搞一个监控线程,来看看到底是出错了,还是卡死了。

new Thread(new WatchThread(travel)).start();


public class WatchThread implements Runnable {

    private FileTravel travel = null;

    public WatchThread(FileTravel travel) {
        this.travel = travel;
    }

    @Override
    public void run() {

        while (!travel.finish) {

            System.out.println("=============");
            System.out.println("当前文件:" + travel.currentFile);
            System.out.println("当前目录数:" + travel.currentForderCnt);
            System.out.println("当前文件数:" + travel.currentFileCnt);

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

原来一直在跑,就是数据量太大了,跑不过来。

为了解决问题,网上查找资料。找到了几个C#的代码,用来处理NTFS磁盘的。抱着对Java的信息,最后决定使用新版本的JDK7带的nio来试试。

public static void main(String[] args) {

        System.out.println("系统启动");

        FileTravel travel = new FileTravel(new File("D:/"));

        long start = System.currentTimeMillis();

        new Thread(new WatchThread(travel)).start();

        travel.travel();
        long end = System.currentTimeMillis();

        System.out.println("耗时:" + ((end - start) / 1000));
    }
public class FileTravelNIO {

    private File forder = null;

    public boolean finish = false;

    public List<FileObject> list = new ArrayList<>();

    public FileTravelNIO(File forder) {
        this.forder = forder;
    }

    public void travel() throws IOException {

        travel(forder, list);
    }

    private void travel(File file, List<FileObject> list) throws IOException {

        Path path = Paths.get(file.getAbsolutePath());

        SimpleFileVisitor<Path> finder = new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {

                File tempFile = file.toFile();

                FileObject obj = new FileObject(tempFile.getName(), tempFile.length(), tempFile.getAbsolutePath());
                list.add(obj);

                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {

                System.out.println("处理文件失败:" + file.toFile());

                return FileVisitResult.CONTINUE;
            }
        };

        java.nio.file.Files.walkFileTree(path, finder);

        finish = true;
    }
}
public class WatchThreadNIO implements Runnable {

    private FileTravelNIO travel = null;

    public WatchThreadNIO(FileTravelNIO travel) {
        this.travel = travel;
    }

    @Override
    public void run() {

        while (!travel.finish) {

            System.out.println("=============");
            System.out.println("当前处理文件数量:" + travel.list.size());

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

神奇的一幕出现了

处理本地磁盘D,耗时109秒,190万的文件数量。磁盘为NTFS
处理移动硬盘F,耗时1860秒,202万的文件数量。磁盘为extFat

结论:
1、NIO比IO性能提高极大
2、磁盘的格式对结果有影响

相关文章

网友评论

      本文标题:JAVA列出磁盘下的所有文件

      本文链接:https://www.haomeiwen.com/subject/uhgfoxtx.html