计算文件夹大小

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(此为大概数,不准确)以下的时候,多线程反而可能比递归更费时,请谨慎选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值