Created
November 19, 2020 15:37
-
-
Save PiotrJander/a706566ad992c8315770fb144546904b to your computer and use it in GitHub Desktop.
Recursive directory size counting in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lombok.Builder; | |
import lombok.Getter; | |
import lombok.SneakyThrows; | |
import lombok.Value; | |
import java.io.IOException; | |
import java.nio.file.FileVisitResult; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.SimpleFileVisitor; | |
import java.nio.file.attribute.BasicFileAttributes; | |
import java.util.ArrayDeque; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Deque; | |
import java.util.List; | |
public class SizeAnnotatedFileTree { | |
// TODO bool flag to distinguish files from directories | |
@Value | |
@Builder | |
static class Node { | |
private String name; | |
private long size; | |
private List<Node> children; | |
} | |
/** | |
* Builds an abstract representation of a file tree annotated with file/directory sizes. | |
*/ | |
static class SizeFileVisitor extends SimpleFileVisitor<Path> { | |
@Getter | |
private final Deque<List<Node>> stack = new ArrayDeque<>() {{ | |
stack.push(new ArrayList<>()); | |
}}; | |
@Override | |
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { | |
stack.push(new ArrayList<>()); | |
return FileVisitResult.CONTINUE; | |
} | |
@Override | |
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { | |
Node fileNode = new Node(file.getFileName().toString(), Files.size(file), Collections.emptyList()); | |
stack.peek().add(fileNode); | |
return FileVisitResult.CONTINUE; | |
} | |
@Override | |
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { | |
List<Node> children = stack.pop(); | |
long directorySize = children.stream().mapToLong(Node::getSize).sum(); | |
Node dirNode = new Node(dir.getFileName().toString(), directorySize, children); | |
stack.peek().add(dirNode); | |
return FileVisitResult.CONTINUE; | |
} | |
} | |
@SneakyThrows | |
public Node getAbstractFileTree(Path root) { | |
SizeFileVisitor visitor = new SizeFileVisitor(); | |
Files.walkFileTree(root, visitor); | |
return visitor.getStack().peek().get(0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment