打印目录树

时间:2012-05-18 15:04:26

标签: java algorithm

我必须打印目录树(如树命令),例如:

 .
 +---A
 |   +---IMAGES
 |       +---BACKUP
 +---ADOKS
 |   +---ROZDZIAL_2
 |   +---ROZDZIAL_3
 |   +---ROZDZIAL_4
 +---AMSC2005
 |   +---AMSC2004
 +---FCCS2005
 |   +---source
 |   +---TMP
 +---LODZ2004
 +---ZAKOPANE2004
 +---DYDAKTYKA
 |   +---DYDAKTYKA_ISI
 |   |   +---COLLS
 |   |   |   +---Q1
 |   |   |   +---Q2
 |   |   |   +---RAZEM
 |   |   |       +---RYSUNKI_COLL1
 |   |   |       +---RYSUNKI_COLL2
 |   |   +---IMAGES
 |   |   +---src
 |   |   +---WYKLAD5
 |   +---DYDAKTYKA_PRG
 |       +---images
 |       +---POMOC
 +---DYDAKTYKA_KST
 |   +---images
 |   +---src
 +---DYDAKTYKA_WPR
     +---images
     +---src

我尝试使用以下代码:

private static void getInto(String p, int n) {
    File path = new File(p);
    File[] list = path.listFiles();

    for (int i = 0; i < list.length; i++) {
        if (list[i].isDirectorhowny()) {
            for (int j = 0; j < n; j++)
                if (WHAT HERE?)
                    System.out.print("|  ");
                else
                    System.out.print("   ");

            System.out.println("+--" + list[i].getName().toString());

            getInto(list[i].getPath(), n + 1);
        }
    }
}

我试过几个版本,但它仍然不起作用。这该怎么做?如果有什么条件?我知道很简单,但我不能这样做。

10 个答案:

答案 0 :(得分:23)

这就是我做到的。

守则

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();
}
}

结果

+--folder1/
|  +--a.txt
|  +--folder2/
|  |  +--b1.txt
|  |  +--b2.txt
|  |  +--b3.txt
|  |  +--folder3/
|  +--folder4/

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);
}

}

答案 1 :(得分:6)

这是我的解决方案:

TreeNode类是从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, "    "));
    }
}

使用此输出:

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

答案 2 :(得分:4)

你需要打印出来的“|”无论何时在相应的级别,您都处理最后一个条目,而是最后一个条目之一。你需要分别知道每个级别的这个,所以你可以添加一个位掩码或一个字符串(比如说)作为'getInto'的额外参数。

答案 3 :(得分:1)

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());

            }
        }
    }
}

}

工作正常......逻辑是正确的

答案 4 :(得分:1)

这是我的代码。它的工作

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());
            }
        }
    }
}

答案 5 :(得分:0)

想想这样 -

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);

希望有所帮助。

答案 6 :(得分:0)

  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

答案 7 :(得分:0)

这是我的解决方案:

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());
                }
        }
    }
}

答案 8 :(得分:0)

我正在使用@ tan70编写的最多更新标记测试该解决方案,但是它在打印主目录时导致了空指针异常。我进行了一些调查,发现listFiles()可以返回null。

公共文件[] listFiles()

返回一个抽象路径名数组,该数组表示此抽象路径名表示的目录中的文件。

如果此抽象路径名不表示目录,则此方法返回 null 。否则,将返回一个File对象数组,目录中的每个文件或目录一个

/**
 * 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();
}

答案 9 :(得分:0)

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();
        }

    }
}

具有以下输出:

.
├── .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