JAVA读取文件夹大小的几种方法实例
(一)单线程递归方式
package com.taobao.test;
import java.io.file;
public class totalfilesizesequential {
public static string filename = "c:\\documents and settings\\administrator\\桌面\\monkeytalk";
// 递归方式 计算文件的大小
private long gettotalsizeoffilesindir(final 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 += gettotalsizeoffilesindir(child);
return total;
}
public static void main(final string[] args) {
final long start = system.nanotime();
final long total = new totalfilesizesequential()
.gettotalsizeoffilesindir(new file(filename));
final long end = system.nanotime();
system.out.println("total size: " + total);
system.out.println("time taken: " + (end - start) / 1.0e9);
}
}
(二)使用executors.newfixedthreadpool和callable 多线程实现
package com.taobao.test;
import java.io.file;
import java.util.arraylist;
import java.util.collections;
import java.util.list;
import java.util.concurrent.callable;
import java.util.concurrent.executionexception;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.concurrent.future;
import java.util.concurrent.timeunit;
import java.util.concurrent.timeoutexception;
public class concurrenttotalfilesize {
public static final string filename = "c:\\documents and settings\\administrator\\桌面\\monkeytalk";
class subdirectoriesandsize {
final public long size;
final public list<file> subdirectories;
public subdirectoriesandsize(final long totalsize,
final list<file> thesubdirs) {
size = totalsize;
subdirectories = collections.unmodifiablelist(thesubdirs);
}
}
private subdirectoriesandsize gettotalandsubdirs(final file file) {
long total = 0;
final list<file> subdirectories = new arraylist<file>();
if (file.isdirectory()) {
final file[] children = file.listfiles();
if (children != null)
for (final file child : children) {
if (child.isfile())
total += child.length();
else
subdirectories.add(child);
}
}
return new subdirectoriesandsize(total, subdirectories);
}
private long gettotalsizeoffilesindir(final file file)
throws interruptedexception, executionexception, timeoutexception {
final executorservice service = executors.newfixedthreadpool(100);
try {
long total = 0;
final list<file> directories = new arraylist<file>();
directories.add(file);
while (!directories.isempty()) {
final list<future<subdirectoriesandsize>> partialresults = new arraylist<future<subdirectoriesandsize>>();
for (final file directory : directories) {
partialresults.add(service
.submit(new callable<subdirectoriesandsize>() {
public subdirectoriesandsize call() {
return gettotalandsubdirs(directory);
}
}));
}
directories.clear();
for (final future<subdirectoriesandsize> partialresultfuture : partialresults) {
final subdirectoriesandsize subdirectoriesandsize = partialresultfuture
.get(100, timeunit.seconds);
directories.addall(subdirectoriesandsize.subdirectories);
total += subdirectoriesandsize.size;
}
}
return total;
} finally {
service.shutdown();
}
}
public static void main(final string[] args) throws interruptedexception,
executionexception, timeoutexception {
final long start = system.nanotime();
final long total = new concurrenttotalfilesize()
.gettotalsizeoffilesindir(new file(filename));
final long end = system.nanotime();
system.out.println("total size: " + total);
system.out.println("time taken: " + (end - start) / 1.0e9);
}
}
(三)使用executors.newfixedthreadpool和callable 多线程的另外一种实现
package com.taobao.test;
import java.io.file;
import java.util.arraylist;
import java.util.list;
import java.util.concurrent.callable;
import java.util.concurrent.executionexception;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.concurrent.future;
import java.util.concurrent.timeunit;
import java.util.concurrent.timeoutexception;
public class naivelyconcurrenttotalfilesize {
public static string filename = "c:\\documents and settings\\administrator\\桌面\\monkeytalk";
private long gettotalsizeoffilesindir(final executorservice service,
final file file) throws interruptedexception, executionexception,
timeoutexception {
if (file.isfile())
return file.length();
long total = 0;
final file[] children = file.listfiles();
if (children != null) {
final list<future<long>> partialtotalfutures = new arraylist<future<long>>();
for (final file child : children) {
partialtotalfutures.add(service.submit(new callable<long>() {
public long call() throws interruptedexception,
executionexception, timeoutexception {
return gettotalsizeoffilesindir(service, child);
}
}));
}
for (final future<long> partialtotalfuture : partialtotalfutures)
total += partialtotalfuture.get(100, timeunit.seconds);
}
return total;
}
private long gettotalsizeoffile(final string filename)
throws interruptedexception, executionexception, timeoutexception {
final executorservice service = executors.newfixedthreadpool(100);
try {
return gettotalsizeoffilesindir(service, new file(filename));
} finally {
service.shutdown();
}
}
public static void main(final string[] args) throws interruptedexception,
executionexception, timeoutexception {
final long start = system.nanotime();
final long total = new naivelyconcurrenttotalfilesize()
.gettotalsizeoffile(filename);
final long end = system.nanotime();
system.out.println("total size: " + total);
system.out.println("time taken: " + (end - start) / 1.0e9);
}
}
(四)使用countdownlatch和atomiclong实现多线程下的并发控制
package com.taobao.test;
import java.io.file;
import java.util.concurrent.countdownlatch;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.concurrent.timeunit;
import java.util.concurrent.atomic.atomiclong;
public class concurrenttotalfilesizewlatch {
private executorservice service;
final private atomiclong pendingfilevisits = new atomiclong();
final private atomiclong totalsize = new atomiclong();
final private countdownlatch latch = new countdownlatch(1);
public static string filename = "c:\\documents and settings\\administrator\\桌面\\monkeytalk";
private void updatetotalsizeoffilesindir(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 {
pendingfilevisits.incrementandget();
service.execute(new runnable() {
public void run() {
updatetotalsizeoffilesindir(child);
}
});
}
}
}
}
totalsize.addandget(filesize);
if (pendingfilevisits.decrementandget() == 0)
latch.countdown();
}
private long gettotalsizeoffile(final string filename)
throws interruptedexception {
service = executors.newfixedthreadpool(100);
pendingfilevisits.incrementandget();
try {
updatetotalsizeoffilesindir(new file(filename));
latch.await(100, timeunit.seconds);
return totalsize.longvalue();
} finally {
service.shutdown();
}
}
public static void main(final string[] args) throws interruptedexception {
final long start = system.nanotime();
final long total = new concurrenttotalfilesizewlatch()
.gettotalsizeoffile(filename);
final long end = system.nanotime();
system.out.println("total size: " + total);
system.out.println("time taken: " + (end - start) / 1.0e9);
}
}
(五)使用blockingqueue和atomiclong的实现
package com.taobao.test;
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;
public class concurrenttotalfilesizewqueue {
public static string filename = "c:\\documents and settings\\administrator\\桌面\\monkeytalk";
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();
}
private 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();
}
}
public static void main(final string[] args) throws interruptedexception {
final long start = system.nanotime();
final long total = new concurrenttotalfilesizewqueue()
.gettotalsizeoffile(filename);
final long end = system.nanotime();
system.out.println("total size: " + total);
system.out.println("time taken: " + (end - start) / 1.0e9);
}
}
(六)使用jdk7的forkjoin来实现
package com.taobao.test;
import java.io.file;
import java.util.arraylist;
import java.util.list;
import java.util.concurrent.forkjoinpool;
import java.util.concurrent.forkjointask;
import java.util.concurrent.recursivetask;
public class filesize {
private final static forkjoinpool forkjoinpool = new forkjoinpool();
public static string filename = "c:\\documents and settings\\administrator\\桌面\\monkeytalk";
private static class filesizefinder extends recursivetask<long> {
final file file;
public filesizefinder(final file thefile) {
file = thefile;
}
@override
public long compute() {
long size = 0;
if (file.isfile()) {
size = file.length();
} else {
final file[] children = file.listfiles();
if (children != null) {
list<forkjointask<long>> tasks = new arraylist<forkjointask<long>>();
for (final file child : children) {
if (child.isfile()) {
size += child.length();
} else {
tasks.add(new filesizefinder(child));
}
}
for (final forkjointask<long> task : invokeall(tasks)) {
size += task.join();
}
}
}
return size;
}
}
public static void main(final string[] args) {
final long start = system.nanotime();
final long total = forkjoinpool.invoke(new filesizefinder(new file("/home")));
final long end = system.nanotime();
system.out.println("total size: " + total);
system.out.println("time taken: " + (end - start) / 1.0e9);
}
}