Skip to content

Instantly share code, notes, and snippets.

@PiotrJander
Created November 19, 2020 15:37
Show Gist options
  • Save PiotrJander/a706566ad992c8315770fb144546904b to your computer and use it in GitHub Desktop.
Save PiotrJander/a706566ad992c8315770fb144546904b to your computer and use it in GitHub Desktop.
Recursive directory size counting in Java
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