I have to print a directory tree (like tree command), example:
.
+---A
| +---IMAGES
| +---BACKUP
+---ADOKS
| +---ROZDZIAL_2
| +---ROZDZIAL
I was testing the solution with the most upticks written by @tan70 however it caused a null pointer exception on printing my home directory. I did some investigation and found that listFiles() can return null.
public File[] listFiles()
Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname.
If this abstract pathname does not denote a directory, then this method returns null. Otherwise an array of File objects is returned, one for each file or directory in the directory
/**
* Pretty print the directory tree and its file names.
*
* @param path
* @return
*/
public static String printDirectoryTree(String path) {
File folder = new File(path);
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
int indent = 0;
StringBuilder sb = new StringBuilder();
printDirectoryTree(folder, indent, sb);
return sb.toString();
}
private static void printDirectoryTree(File folder, int indent, StringBuilder sb) {
if (folder != null && folder.isDirectory() && folder.listFiles() != null) {
sb.append(getIndentString(indent));
sb.append("+--");
sb.append(folder.getName());
sb.append("/");
sb.append("\n");
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
printDirectoryTree(file, indent + 1, sb);
} else {
printFile(file, indent + 1, sb);
}
}
}
}
private static void printFile(File file, int indent, StringBuilder sb) {
sb.append(getIndentString(indent));
sb.append("+--");
if (file != null) {
sb.append(file.getName());
} else {
sb.append("null file name");
}
sb.append("\n");
}
private static String getIndentString(int indent) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indent; i++) {
sb.append("| ");
}
return sb.toString();
}
Reference and modify fucntions of tree structures from this:
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TreeNode<T> implements Iterable<TreeNode<T>> {
public T data;
public TreeNode<T> parent;
public List<TreeNode<T>> children;
public boolean isRoot() {
return parent == null;
}
public boolean isLeaf() {
return children.size() == 0;
}
private List<TreeNode<T>> elementsIndex;
public TreeNode(T data) {
this.data = data;
this.children = new LinkedList<TreeNode<T>>();
this.elementsIndex = new LinkedList<TreeNode<T>>();
this.elementsIndex.add(this);
}
public TreeNode<T> addChild(T child) {
TreeNode<T> childNode = new TreeNode<T>(child);
childNode.parent = this;
this.children.add(childNode);
this.registerChildForSearch(childNode);
return childNode;
}
public int getLevel() {
if (this.isRoot())
return 0;
else
return parent.getLevel() + 1;
}
private void registerChildForSearch(TreeNode<T> node) {
elementsIndex.add(node);
if (parent != null)
parent.registerChildForSearch(node);
}
public TreeNode<T> findTreeNode(Comparable<T> cmp) {
for (TreeNode<T> element : this.elementsIndex) {
T elData = element.data;
if (cmp.compareTo(elData) == 0)
return element;
}
return null;
}
@Override
public String toString() {
return data != null ? data.toString() : "[data null]";
}
@Override
public Iterator<TreeNode<T>> iterator() {
TreeNodeIter<T> iter = new TreeNodeIter<T>(this);
return iter;
}
public static TreeNode<File> createDirTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a
Directory");
}
TreeNode<File> DirRoot = new TreeNode<File>(folder);
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
appendDirTree(file, DirRoot);
} else {
appendFile(file, DirRoot);
}
}
return DirRoot;
}
public static void appendDirTree(File folder, TreeNode<File> DirRoot)
{
DirRoot.addChild(folder);
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
appendDirTree(file,
DirRoot.children.get(DirRoot.children.size() - 1));
} else {
appendFile(file,
DirRoot.children.get(DirRoot.children.size() - 1));
}
}
}
public static void appendFile(File file, TreeNode<File> filenode) {
filenode.addChild(file);
}
public static String renderDirectoryTree(TreeNode<File> tree) {
List<StringBuilder> lines = renderDirectoryTreeLines(tree);
String newline = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder(lines.size() * 20);
for (StringBuilder line : lines) {
sb.append(line);
sb.append(newline);
}
return sb.toString();
}
public static List<StringBuilder>
renderDirectoryTreeLines(TreeNode<File>
tree) {
List<StringBuilder> result = new LinkedList<>();
result.add(new StringBuilder().append(tree.data.getName()));
Iterator<TreeNode<File>> iterator = tree.children.iterator();
while (iterator.hasNext()) {
List<StringBuilder> subtree =
renderDirectoryTreeLines(iterator.next());
if (iterator.hasNext()) {
addSubtree(result, subtree);
} else {
addLastSubtree(result, subtree);
}
}
return result;
}
private static void addSubtree(List<StringBuilder> result,
List<StringBuilder> subtree) {
Iterator<StringBuilder> iterator = subtree.iterator();
//subtree generated by renderDirectoryTreeLines has at least one
line which is tree.getData()
result.add(iterator.next().insert(0, "├── "));
while (iterator.hasNext()) {
result.add(iterator.next().insert(0, "│ "));
}
}
private static void addLastSubtree(List<StringBuilder> result,
List<StringBuilder> subtree) {
Iterator<StringBuilder> iterator = subtree.iterator();
//subtree generated by renderDirectoryTreeLines has at least
one
line which is tree.getData()
result.add(iterator.next().insert(0, "└── "));
while (iterator.hasNext()) {
result.add(iterator.next().insert(0, " "));
}
}
public static void main(String[] args) {
File file = new File("./");
TreeNode<File> DirTree = createDirTree(file);
String result = renderDirectoryTree(DirTree);
System.out.println(result);
try {
File newTextFile = new File("./DirectoryTree.txt");
FileWriter fw = new FileWriter(newTextFile);
fw.write(result);
fw.close();
} catch (IOException iox) {
iox.printStackTrace();
}
}
}
with this output:
.
├── .DS_Store
├── .idea
│ ├── compiler.xml
│ ├── dictionaries
│ │ └── yankai01.xml
│ ├── encodings.xml
│ ├── misc.xml
│ └── workspace.xml
├── data_exploring.iml
├── pom.xml
├── src
│ ├── .DS_Store
│ ├── main
│ │ ├── .DS_Store
│ │ ├── java
│ │ │ ├── FileAssert.java
│ │ │ ├── HttpUtils.java
│ │ │ ├── QuerySaveToCsv.java
│ │ │ ├── SampleData.java
│ │ │ ├── SampleIterating.java
│ │ │ ├── SampleSearching.java
│ │ │ ├── TreeNode.java
│ │ │ └── TreeNodeIter.java
│ │ └── resources
│ └── test
│ └── java
└── target
├── classes
│ ├── FileAssert.class
│ ├── HttpUtils.class
│ ├── QuerySaveToCsv.class
│ ├── SampleData.class
│ ├── SampleIterating.class
│ ├── SampleSearching$1.class
│ ├── SampleSearching.class
│ ├── TreeNode.class
│ ├── TreeNodeIter$ProcessStages.class
│ └── TreeNodeIter.class
└── generated-sources
└── annotations
This is My Code. its Work
package DIRS;
import java.io.File;
public class LISTDIR
{
public static void main(String[] args)
{
String path = System.getProperty("user.dir")+File.separator;
File file[] = new File(path).listFiles();
for(int i = 0 ; i < file.length ; i++)
{
if(file[i].isDirectory())
{
System.out.println("->"+file[i].getName());
new LISTDIR().listfiles(file[i],"--");
}
else
{
System.out.println("-> "+file[i].getName());
}
}
}
public void listfiles(File f,String sprtr)
{
File file[] = f.listFiles();
for(int i = 0 ; i < file.length ; i++)
{
if(file[i].isDirectory())
{
System.out.println(sprtr+file[i].getName());
new LISTDIR().listfiles(file[i],"--"+sprtr);
}
else
{
System.out.println(sprtr+file[i].getName());
}
}
}
}
This is my solution:
import java.io.File;
public class MostrarArbol {
public static void main(String args[]) {
File carpeta = new File(args[0]);
// File carpeta = new File(".");
if (!carpeta.exists()) {
System.out.println(args[0] + " NO existe.");
return;
}
imprimeArbol(carpeta, "");
}
public static void imprimeArbol(File carpeta, String tabulador) {
File contenido[] = carpeta.listFiles();
if (contenido != null) {
for (int i = 0; i < contenido.length; i++)
if (contenido[i].isDirectory()) {
System.out.println(tabulador + "|-" + contenido[i].getName());
imprimeArbol(contenido[i], tabulador + "| ");
} else {
System.out.println(tabulador + "+-" + contenido[i].getName().toString());
}
}
}
}
import java.io.File;
public class Tree
{
public static void main(String[] args) throws Exception
{
File folder = new File((args.length >= 1 && args[0].length() > 0)
? args[0]
: ".");
if (!folder.isDirectory())
{
throw new IllegalArgumentException("Invalid directory: " + folder.getName());
}
int level = 0;
System.out.println(renderFolder(folder, level, new StringBuilder(), false));
}
private static StringBuilder renderFolder(File folder, int level, StringBuilder sb, boolean isLast)
{
indent(sb, level, isLast).append("[D] ").append(folder.getName()).append("\n");
File[] objects = folder.listFiles();
for (int i = 0; i < objects.length; i++)
{
boolean last = ((i + 1) == objects.length);
if (objects[i].isDirectory())
{
renderFolder(objects[i], level + 1, sb, last);
}
else
{
renderFile(objects[i], level + 1, sb, last);
}
}
return sb;
}
private static StringBuilder renderFile(File file, int level, StringBuilder sb, boolean isLast)
{
return indent(sb, level, isLast).append("--- ").append(file.getName()).append("\n");
}
private static StringBuilder indent(StringBuilder sb, int level, boolean isLast)
{
for (int i = 1; i < level; i++)
{
sb.append("| ");
}
if (level > 0)
{
sb.append(isLast
? "`-"
: "|-");
}
return sb;
}
}
[D] .
|-[D] classes
| |-[D] .data
| | `---- Play.cdi_javac
| |---- ArrayListTest$Pair.class
| |---- ArrayListTest.class
| |---- ArrayTest.class
| |-[D] fruit
| | |---- Apple.class
| | `---- GrannySmith.class
| |---- IfTest.class
| |-[D] interview
| | |---- Q1.class
| | |---- Q2.class
| | |---- Q3.class
| | |---- Q3Sub.class
| | |---- Q9Sub.class
| | `---- Q9Super.class
| |---- IntOverflowTest.class
| |---- LinkedMapTest.class
| |-[D] log
| | `---- Logger.class
| |---- log.properties
| |---- StringCaseTest.class
| |-[D] test
| | |-[D] cache
| | | |-[D] test1
| | | | |---- Cache.class
| | | | |---- CacheEntry.class
| | | | `---- RevisedCacheTest.class
| | | |-[D] test2
| | | | |---- Cache.class
| | | | |---- Log.class
| | | | `---- RevisedCacheTest.class
| | | `-[D] test3
| | | | |---- ConcurrentCache.class
| | | | `---- ConcurrentCacheTest.class
| | |---- Test.class
| | `---- Test2.class
| |---- Test.class
| |---- Test2.class
| `---- ZipTest.class
`---- Play.jpr
This is how I did it.
The Code
import java.io.File;
public class FileAssert {
/**
* Pretty print the directory tree and its file names.
*
* @param folder
* must be a folder.
* @return
*/
public static String printDirectoryTree(File folder) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
int indent = 0;
StringBuilder sb = new StringBuilder();
printDirectoryTree(folder, indent, sb);
return sb.toString();
}
private static void printDirectoryTree(File folder, int indent,
StringBuilder sb) {
if (!folder.isDirectory()) {
throw new IllegalArgumentException("folder is not a Directory");
}
sb.append(getIndentString(indent));
sb.append("+--");
sb.append(folder.getName());
sb.append("/");
sb.append("\n");
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
printDirectoryTree(file, indent + 1, sb);
} else {
printFile(file, indent + 1, sb);
}
}
}
private static void printFile(File file, int indent, StringBuilder sb) {
sb.append(getIndentString(indent));
sb.append("+--");
sb.append(file.getName());
sb.append("\n");
}
private static String getIndentString(int indent) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indent; i++) {
sb.append("| ");
}
return sb.toString();
}
}
The Result
+--folder1/
| +--a.txt
| +--folder2/
| | +--b1.txt
| | +--b2.txt
| | +--b3.txt
| | +--folder3/
| +--folder4/
The UnitTest
import static org.junit.Assert.*;
import java.io.File;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class FileAssertTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private File folder1;
@Before
public void setUp() {
folder1 = temporaryFolder.newFolder("folder1");
}
@Test
public void testPrintDirectoryTreeWhenFolderIsEmpty() {
// Invoke
String actual = FileAssert.printDirectoryTree(folder1);
// Verify
assertEquals("+--folder1/\n", actual);
}
private static final String EXPECTED_FCOF = "" + "+--folder1/\n"
+ "| +--a.txt\n";
@Test
public void testPrintDirectoryTreeWhenFolderContainsOneFile()
throws Exception {
// Setup
File aFile = new File(folder1, "a.txt");
assertTrue(aFile.createNewFile());
// Invoke
String actual = FileAssert.printDirectoryTree(folder1);
// Verify
assertEquals(EXPECTED_FCOF, actual);
}
private static final String EXPECTED_COMPLEX = "+--folder1/\n"
+ "| +--a.txt\n" + "| +--folder2/\n" + "| | +--b1.txt\n"
+ "| | +--b2.txt\n" + "| | +--b3.txt\n" + "| | +--folder3/\n"
+ "| +--folder4/\n";
@Test
public void testPrintDirectoryTreeComplex() throws Exception {
// Setup
File aFile = new File(folder1, "a.txt");
assertTrue(aFile.createNewFile());
File folder2 = new File(folder1, "folder2");
assertTrue(folder2.mkdir());
File b1File = new File(folder2, "b1.txt");
assertTrue(b1File.createNewFile());
File b2File = new File(folder2, "b2.txt");
assertTrue(b2File.createNewFile());
File folder3 = new File(folder2, "folder3");
assertTrue(folder3.mkdir());
File b3File = new File(folder2, "b3.txt");
assertTrue(b3File.createNewFile());
File folder4 = new File(folder1, "folder4");
assertTrue(folder4.mkdir());
// Invoke
String actual = FileAssert.printDirectoryTree(folder1);
// Verify
assertEquals(EXPECTED_COMPLEX, actual);
}
}
file directory printing pretty-printing