I have to print a directory tree (like tree command), example:
.
+---A
| +---IMAGES
| +---BACKUP
+---ADOKS
| +---ROZDZIAL_2
| +---ROZDZIAL
This is my solution:
(The TreeNode
Class is copied from there.)
public static String renderDirectoryTree(TreeNode<FileInformation> 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<FileInformation> tree) {
List<StringBuilder> result = new LinkedList<>();
result.add(new StringBuilder().append(tree.getData().getPath().getFileName()));
Iterator<TreeNode<FileInformation>> iterator = tree.getChildren().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, " "));
}
}
with this output:
DirectoryCatalog
├── .git
│ ├── COMMIT_EDITMSG
│ ├── config
│ ├── description
│ ├── HEAD
│ ├── hooks
│ │ ├── applypatch-msg.sample
│ │ ├── commit-msg.sample
│ │ ├── post-commit.sample
│ │ ├── post-receive.sample
│ │ ├── post-update.sample
│ │ ├── pre-applypatch.sample
│ │ ├── pre-commit.sample
│ │ ├── pre-push.sample
│ │ ├── pre-rebase.sample
│ │ ├── prepare-commit-msg.sample
│ │ └── update.sample
│ ├── index
│ ├── info
│ │ └── exclude
│ ├── logs
│ │ ├── HEAD
│ │ └── refs
│ │ ├── heads
│ │ │ └── master
│ │ └── remotes
│ │ └── origin
│ │ └── master
│ ├── objects
│ │ ├── 0b
│ │ │ └── b3fb0a15268c9770220938b1048305429527c7
│ │ ├── 0d
│ │ │ └── e508f20f1cb44ff543cec54ea93a71e5e40d1d
│ │ ├── 10
│ │ │ └── 9c753f3aab08f167f8409e6c9abec27cad6548
│ │ ├── 15
│ │ │ └── 7602556ebd120e656ae8dcd00cb361bfb3ef79
│ │ ├── 16
│ │ │ └── 952a5d1f5f3d15199f3e85b3d895a81990024e
│ │ ├── 1c
│ │ │ └── 5b36cd4d41b9b7d0df46d4184512098186c904
│ │ ├── 20
│ │ │ └── ae5cc82ebbb85f9161d8fd9783905e4cbee72c
│ │ ├── 21
│ │ │ └── e42add0fb2205a75ff621dbeb6d76455816b79
│ │ ├── 23
│ │ │ └── af4eaa4007ca941e562406b7b329c6ba4b395e
│ │ ├── 28
│ │ │ └── 6caf4b7be3ac85a476f3782220fe167a040971
│ │ ├── 2b
│ │ │ └── f6743fb97162e999fb6429510bb8a52114bc31
│ │ ├── 35
│ │ │ └── acd4ab6acb599d4e3244be2a8dc3a0161bcb3c
│ │ ├── 46
│ │ │ └── 1ef7c4db86e0466bb8f1f81dc25f12e3598db6
│ │ ├── 47
│ │ │ └── 4ce7f18330e5295ab1ef2eea66505235819e22
│ │ ├── 4b
│ │ │ └── 825dc642cb6eb9a060e54bf8d69288fbee4904
│ │ ├── 4e
│ │ │ └── 4e047c077c7825a845deebda7f97832cee847b
│ │ ├── 4f
│ │ │ └── 20b118269d71535e469966fdb5fe8a78ae6c9a
│ │ ├── 51
│ │ │ └── 677b295b4cd9931354dd52fb6050015d524fea
│ │ ├── 52
│ │ │ └── 9c34997d8262bd207037f0373703d68d4e1a4e
│ │ ├── 5b
│ │ │ └── 928f45816cc51609861f0930251accbe7de7f9
│ │ ├── 5d
│ │ │ └── 7cdbe029c6eff99c72d09b0a81347b605e77d7
│ │ ├── 61
│ │ │ └── 2b9d86f6ac365ede894e13a6273fd13833f44f
│ │ ├── 67
│ │ │ └── 2209cb240eac0303d6e3b6c7eb04242d661fad
│ │ ├── 6b
│ │ │ ├── c84e19913908f16141677b9d66abdb620350a0
│ │ │ └── d278b63be854ccd3c02b9038ee43366021b1a1
│ │ ├── 6c
│ │ │ └── 9d10e91679988caaee6759d48daf336f28a9a3
│ │ ├── 70
│ │ │ └── 4284c78f1c664c1348af5a784cca55c51fd66a
│ │ ├── 72
│ │ │ └── 1ab5fe4e4226930668048d97331103a92751be
│ │ ├── 78
│ │ │ └── 64a41eaf50f32ae8d2cab1acd200c405215c1a
│ │ ├── 82
│ │ │ └── 36f772feca12b3e301eea50774458a7e77c7fb
│ │ ├── 83
│ │ │ └── bc1e2a1f3187f28d63d7fa334744810d80c20d
│ │ ├── 87
│ │ │ └── 3ce97f624e9a1ae4a1bbf41218d50dc3503d6f
│ │ ├── 8a
│ │ │ └── 0b282aa6885fb573c106b3551f7275c5f17e8e
│ │ ├── 91
│ │ │ └── a7e269e19dfc62e27137a0b57ef3e430cee4fd
│ │ ├── 94
│ │ │ ├── 065a39b0dd7ce05604b96aff84d984493553e2
│ │ │ └── 5cbc994fb2d251437e71edf3a6eb289c5836ec
│ │ ├── 95
│ │ │ └── f481326b62c9adff2a0dad47480e279adb518f
│ │ ├── 9e
│ │ │ └── 1f7de67de38e67479cb8e38ad92d6354838393
│ │ ├── a1
│ │ │ └── e385dff1fb08b7a45ea52af43b22d240f0adab
│ │ ├── a7
│ │ │ └── 8934a5a81d95a85b9c97a3e1c1429186feb83d
│ │ ├── ab
│ │ │ └── 855c3379bdb3e4a22605de58f3438148d6ffe7
│ │ ├── b7
│ │ │ └── 64eafa2ba4e7f8f52a4e96da61b3d77f262d16
│ │ ├── bd
│ │ │ └── 9374662b409bb364779212874e7cf611541c38
│ │ ├── c1
│ │ │ └── f858c163f9c8cb89a145a60e87c9e35c97fb93
│ │ ├── c3
│ │ │ └── 35d07a1078656646ca6e980b468b938106d357
│ │ ├── c5
│ │ │ └── ac562c59d6a0430fa0ccd1fa6318fa5d48604f
│ │ ├── c8
│ │ │ └── f3d9284a65afbff6640da7970664ee2134c85b
│ │ ├── c9
│ │ │ └── 7a8bdb9088d370da7e88784a7a093b971aa23a
│ │ ├── cc
│ │ │ └── a6a5141b614b5e351c7e5b6b677ef09a931786
│ │ ├── d1
│ │ │ └── 76229a9e1d0172f84d060904d171be51f9d0f6
│ │ ├── d3
│ │ │ ├── 2f0a1ba59a0c52d3acc62de1d624fb68423ee3
│ │ │ └── b9dfcb3216a2feab03b1ae96280e3c1c963953
│ │ ├── e0
│ │ │ └── 6d2081865a766a8668acc12878f98b27fc9ea0
│ │ ├── e5
│ │ │ └── 3106578cd8adcd085c5c63c05fc49d5a5a3dbb
│ │ ├── info
│ │ └── pack
│ └── refs
│ ├── heads
│ │ └── master
│ ├── remotes
│ │ └── origin
│ │ └── master
│ └── tags
├── .gitattributes
├── .gitignore
├── .gradle
│ └── 2.2.1
│ └── taskArtifacts
│ ├── cache.properties
│ ├── cache.properties.lock
│ ├── fileHashes.bin
│ ├── fileSnapshots.bin
│ ├── outputFileStates.bin
│ └── taskArtifacts.bin
├── .idea
│ ├── .name
│ ├── compiler.xml
│ ├── copyright
│ │ └── profiles_settings.xml
│ ├── encodings.xml
│ ├── gradle.xml
│ ├── libraries
│ │ ├── Gradle__commons_io_commons_io_2_4.xml
│ │ ├── Gradle__junit_junit_4_11.xml
│ │ └── Gradle__org_hamcrest_hamcrest_core_1_3.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── scopes
│ │ └── scope_settings.xml
│ ├── uiDesigner.xml
│ ├── vcs.xml
│ └── workspace.xml
├── app
│ ├── app.iml
│ ├── build
│ │ ├── classes
│ │ │ └── main
│ │ │ └── gq
│ │ │ └── baijie
│ │ │ └── catalog
│ │ │ ├── controllor
│ │ │ │ ├── FilesScanner$MyFileVisitor.class
│ │ │ │ └── FilesScanner.class
│ │ │ ├── entity
│ │ │ │ └── FileInformation.class
│ │ │ ├── Main.class
│ │ │ └── util
│ │ │ ├── FileAssert.class
│ │ │ ├── Hash.class
│ │ │ ├── HEX.class
│ │ │ ├── Printer$1.class
│ │ │ ├── Printer$DirectoryTreeRender.class
│ │ │ ├── Printer.class
│ │ │ └── TreeNode.class
│ │ ├── dependency-cache
│ │ ├── resources
│ │ │ └── main
│ │ └── tmp
│ │ └── compileJava
│ ├── build.gradle
│ └── src
│ ├── main
│ │ └── java
│ │ └── gq
│ │ └── baijie
│ │ └── catalog
│ │ ├── controllor
│ │ │ └── FilesScanner.java
│ │ ├── entity
│ │ │ └── FileInformation.java
│ │ ├── Main.java
│ │ └── util
│ │ ├── FileAssert.java
│ │ ├── Hash.java
│ │ ├── HEX.java
│ │ ├── Printer.java
│ │ └── TreeNode.java
│ └── test
│ └── java
├── DirectoryCatalog.iml
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── LICENSE
├── README.md
├── settings.gradle
└── temp
├── 150110161006.txt
├── 150110173453.txt
├── 150110175353.txt
├── 150111111311.txt
├── 150111112500.txt
├── 150111113411.txt
├── 150111155619.txt
├── 150111161958.txt
├── 150111162230.txt
├── 150111162632.txt
├── 150111163225.txt
├── 150111163330.txt
├── 150111164526.txt
├── 150111205412.txt
├── 150111210322.txt
├── 150111210506.txt
├── 150111210927.txt
├── 150111211249.txt
├── 150111211321.txt
├── 150111220750.txt
├── 150111220822.txt
├── 150111221437.txt
├── 150111221842.txt
├── 150111222437.txt
├── 150111234344.txt
├── 150111234433.txt
└── 150112000034.txt
import java.io.File;
public class MainEntry {
public static void main(String[] args) {
walkin(new File("/home/user")); //Replace this with a suitable directory
}
/**
* Recursive function to descend into the directory tree and find all the files
@param dir A file object defining the top directory
**/
public static void walkin(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i=0; i<listFile.length; i++) {
if (listFile[i].isDirectory()) {
System.out.println("|\t\t");
walkin(listFile[i]);
} else {
System.out.println("+---"+listFile[i].getName().toString());
}
}
}
}
}
Will work fine..The Logic is correct
Think of it like this -
procedure printOutput(file, depth):
print "| " depth times;
print "+---" + file name;
print new line
if(file is a directory):
for(each file inside file, say innerFile):
call printOutput(innerFile, depth + 1);
Hope that helps.
You need to print out "|" whenever on the corresponding level you are not processing the last entry, but one of the entries before the last. You need to know this for every level separately, so you could add a bit mask or a string (say) as an extra argument to 'getInto'.