Having this kind of subdirectories:
C:\test\foo\a.dat (100kb)
C:\test\foo\b.dat (200kb)
C:\test\foo\another_dir\jim.dat (500kb)
C:\test\bar\ball.jpg (5kb)
C:\test\bar\sam\sam1.jpg (100kb)
C:\test\bar\sam\sam2.jpg (300kb)
C:\test\somefile.dat (700kb)
I want to get size of all subdirectories, but only show the top directory, Running the command java DU c:\\test should produce the following output:
DIR C:\TEST\FOO 800KB
FILE C:\TEST\SOMEFILE.DAT 700KB
DIR C:\TEST\BAR 405KB
any help will be great, my code so far is close but not getting the expected output ? :/
import java.io.File;
public class DU {
public static void main(String[] args) {
File file = new File(args[0]);
if (file.isDirectory()) {
File[] filesNames = file.listFiles();
for (File temp : filesNames) {
if (temp.isDirectory()) {
File dirs = new File(temp.getPath());
getDirSize(dirs);
} else {
System.out.println("FILE - " + temp.getPath() + " "
+ friendlyFileSize(temp.length()));
}
}
} else {
System.out.println("THIS IS NOT A FILE LOCATION!");
}
}
private static long getDirSize(File dirs) {
long size = 0;
for (File file : dirs.listFiles()) {
if (file.isFile())
size += file.length();
else
size += getDirSize(file);
}
System.out.println("DIR - " + dirs+" "+ friendlyFileSize(size));
return size;
}
public static String friendlyFileSize(long size) {
String unit = "bytes";
if (size > 1024) {
size = size / 1024;
unit = "kb";
}
if (size > 1024) {
size = size / 1024;
unit = "mb";
}
if (size > 1024) {
size = size / 1024;
unit = "gb";
}
return " (" + size + ")" + unit;
}
}
This code get the output of all subdirectories instead showing a total of all of them and printing just top directory ??? Many thx for any help :D
FILE - c:\test\baba.pdf (4)mb
FILE - c:\test\babdb.txt (67)kb
DIR - c:\test\one\oneone (67)kb
DIR - c:\test\one (814)kb
DIR - c:\test\two\twotwo (322)kb
DIR - c:\test\two (368)kb
Your recquirement is that input a folder then show the sizes of all files(file including folder) of the folder.
We define the size of a folder is the sum of the size of files in the folder(including sub-folder).
So, the process of the source code is below:
(1) list-up all files of the folder as input.
(2) calculate file-size of listing in (1).
(3) show file-type(FILE OR DIR), the paths of files listing in (1), and file-size calculated in (2).
the source code of (1) and (3) is below:
public static void showFileSizes(File dir) {
File[] files = dir.listFiles(); // (1)
long[] fileSizes = new long[files.length];
for(int i = 0; i < files.length; i++) {
fileSizes[i] = calculateFileSize(file[i]);//invoke the method corresponding to (2).
boolean isDirectory = files[i].isDirectory();
System.out.println(((isDirectory)?"DIR":"FILE") + " - " + files[i].getAbsolutePath() + friendlyFileSize(fileSizes[i]));// as (3)
}
}
the source code of (2) is below:
public static long calculateFileSize(File file) {
long fileSize = 0L;
if(file.isDirectory()) {
File[] children = file.listFiles();
for(File child : children) {
fileSize += calculateFileSize(child);
}
}
else {
fileSize = file.length();
}
return fileSize;
}
The only thing you have to do is invoke showFileSizes method.
It is quite easy by using Java 7 new File I/O NIO.2 framework mostly by using Files.walkFileTree(Path, Set, int, FileVisitor) method.
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicLong;
public class Main {
private static class PrintFiles extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
if (attr.isDirectory()) {
try {
System.out.format("Directory: %s, size: %d bytes\n", file, getDirSize(file));
} catch (IOException e) {
e.printStackTrace();
}
} else if (attr.isRegularFile()) {
System.out.format("Regular file: %s, size %d bytes\n", file, attr.size());
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.err.println(exc);
return FileVisitResult.CONTINUE;
}
/**
* Walks through directory path and sums up all files' sizes.
*
* @param dirPath Path to directory.
* @return Total size of all files included in dirPath.
* @throws IOException
*/
private long getDirSize(Path dirPath) throws IOException {
final AtomicLong size = new AtomicLong(0L);
Files.walkFileTree(dirPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
size.addAndGet(attrs.size());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
//just skip
return FileVisitResult.CONTINUE;
}
});
return size.get();
}
}
/**
* Main method.
*
* @param args
*/
public static void main(String [] args) {
Path p = Paths.get("d:\\octopress");
try {
Files.walkFileTree(p, EnumSet.noneOf(FileVisitOption.class), 1, new PrintFiles());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Staying close to what you've already done, you would have to increment the directory size everytime you encounter it.
for (File temp : filesNames) {
if (temp.isDirectory()) {
dirs = new File(temp.getPath());
heavy += getDirSize(dirs);
} else {
System.out.println("FILE - " + temp.getPath() + " "
+ friendlyFileSize(temp.length()));
}
}
You also would want to display the the size after summing it all up against the parent of the subdirectories
public static void main(String[] args) {
...
...
System.out.println("DIR - " + dirs.getParent() + " "
+ friendlyFileSize(heavy));
}
Also, you need to check for whether the directory has any files or not, else dirs.listFiles()
would cause a NPE
private static long getDirSize(File dirs) {
long size = 0;
if (dirs != null && dirs.listFiles() != null) {
for (File file : dirs.listFiles()) {
if (file.isFile())
size += file.length();
else
size += getDirSize(file);
}
}
return size;
}
Your whole code slightly modified:
public class SubDirs {
static long heavy;
public static void main(String[] args) {
File file = new File("C:\\Program Files");
File dirs = null;
if (file.isDirectory()) {
File[] filesNames = file.listFiles();
for (File temp : filesNames) {
if (temp.isDirectory()) {
dirs = new File(temp.getPath());
heavy += getDirSize(dirs);
} else {
System.out.println("FILE - " + temp.getPath() + " "
+ friendlyFileSize(temp.length()));
}
}
} else {
System.out.println("THIS IS NOT A FILE LOCATION!");
}
System.out.println("DIR - " + dirs.getParent() + " "
+ friendlyFileSize(heavy));
}
private static long getDirSize(File dirs) {
long size = 0;
if (dirs != null && dirs.listFiles() != null) {
for (File file : dirs.listFiles()) {
if (file.isFile())
size += file.length();
else
size += getDirSize(file);
}
}
return size;
}
public static String friendlyFileSize(long size) {
String unit = "bytes";
if (size > 1024) {
size = size / 1024;
unit = "kb";
}
if (size > 1024) {
size = size / 1024;
unit = "mb";
}
if (size > 1024) {
size = size / 1024;
unit = "gb";
}
return " (" + size + ")" + unit;
}
}
Keep it short and simple by using FileUtils.sizeOfDirectory(). You have to import org.apache.commons.io.FileUtils for this.
if (temp.isDirectory()) {
File dirs = new File(temp.getPath());
System.out.println("DIR - " + dirs+" "+ friendlyFileSize(FileUtils.sizeOfDirectory(dirs)));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.