计算文件夹大小

来源:互联网 发布:电脑人工智能软件 编辑:程序博客网 时间:2024/04/30 04:23

1.单线程递归获取文件夹大小

    public static long getDirSize(File file) {        if (file.isFile())            return file.length();        final File[] children = file.listFiles();        long total = 0;        if (children != null)            for (final File child : children)                total += getDirSize(child);        return total;    }

2.多线程BlockingQueue

import java.io.File;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicLong;/** * Created by shijack on 2016/7/8. * <p>Attention: when the dir size is larger than 1G the speed can faster than in only one thread!</p> */public class ConcurrentDirSizeCountUtil {    private ExecutorService service;    final private BlockingQueue<Long> fileSizes = new ArrayBlockingQueue<Long>(            500);    final AtomicLong pendingFileVisits = new AtomicLong();    private void startExploreDir(final File file) {        pendingFileVisits.incrementAndGet();        service.execute(new Runnable() {            public void run() {                exploreDir(file);            }        });    }    private void exploreDir(final File file) {        long fileSize = 0;        if (file.isFile())            fileSize = file.length();        else {            final File[] children = file.listFiles();            if (children != null)                for (final File child : children) {                    if (child.isFile())                        fileSize += child.length();                    else {                        startExploreDir(child);                    }                }        }        try {            fileSizes.put(fileSize);        } catch (Exception ex) {            throw new RuntimeException(ex);        }        pendingFileVisits.decrementAndGet();    }    public long getTotalSizeOfFile(final String fileName) throws InterruptedException {        service = Executors.newFixedThreadPool(100);        try {            startExploreDir(new File(fileName));            long totalSize = 0;            while (pendingFileVisits.get() > 0 || fileSizes.size() > 0) {                final Long size = fileSizes.poll(10, TimeUnit.SECONDS);                totalSize += size;            }            return totalSize;        } finally {            service.shutdown();        }    }}

3.多线程Build.VERSION_CODES.LOLLIPOP之后使用ForkJoinTask

import android.annotation.TargetApi;import android.os.Build;import java.io.File;import java.util.ArrayList;import java.util.List;import java.util.Scanner;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.concurrent.RecursiveTask;import java.util.concurrent.TimeoutException;@TargetApi(Build.VERSION_CODES.LOLLIPOP)public class FileSize {    private final static ForkJoinPool forkJoinPool = new ForkJoinPool();    private static class FileSizeFinder extends RecursiveTask<Long> {        File file;        public FileSizeFinder(File file){            this.file = file;        }        @Override        protected Long compute() {            // TODO Auto-generated method stub            long size = 0;            if(file.isFile()){                return file.length();            }else{                File[] children = file.listFiles();                if(children != null){                    List<ForkJoinTask<Long>> tasks = new ArrayList<ForkJoinTask<Long>>();                    for(File child:children){                        if(child.isFile()){                            size += child.length();                        }else{                            tasks.add(new FileSizeFinder(child));                        }                    }                    for(ForkJoinTask<Long> task:invokeAll(tasks)){ //等待所有的子任务完成之后才会执行下一步循环操作。在任务被阻塞时,                        //其他程序也可以去帮忙完成其他任务                        size += task.join();                    }                }            }            return size;        }    }    public static void main(final String[] args)            throws InterruptedException,ExecutionException,TimeoutException {        Scanner scanner = new Scanner(System.in);        String str = scanner.next();        System.out.println("get the output--->" + str);        final long start = System.nanoTime();        final long total = forkJoinPool.invoke(new FileSizeFinder(new File(str)));        final long end = System.nanoTime();        System.out.println("Total Size: " + total);        System.out.println("Time taken: " + (end-start)/1.0e9);    }}

注意:

在文件夹的大小为200M(此为大概数,不准确)以下的时候,多线程反而可能比递归更费时,请谨慎选择。

0 0