递归创建目录

33

有人知道如何使用Java基于字母表(a-z)创建n级深度的子目录吗?

 /a
    /a
        /a
        /b
        /c
        ..
    /b
        /a
        /b
        ..
    ..
        /a
        /b
        /c
        ..

/b
    /a
        /a
        /b
        ..
    /b
        /a
        /b
        ..
    ..
        /a
        /b
        ..
..
    /a
        /a
        /b
        ..
    /b
        /a
        /b
        ..
    ..
        /a
        /b
        ..
10个回答

154
您可以直接使用Java的java.io.File类中的mkdirs()方法。
示例:
new File("C:\\Directory1\\Directory2").mkdirs();

33
自Java 7以来,可以使用Files.createDirectories方法。 - Matt R
这应该被用作正确答案。 - thiagolsilva

12
如果您不介意依赖第三方API,那么Apache Commons IO包可以直接为您完成此操作。请查看FileUtils.ForceMkdir
Apache许可证对商业软件开发非常友好,即它不像GPL那样要求您分发源代码(这可能是好事或坏事,取决于您的观点)。

迄今为止,这是实际目的(即除非它是教育性练习)的最佳答案。并且强制执行“构建”问题:即使是最简单的应用程序也需要构建框架,以避免管理命令行类路径、jar文件位置等。每个程序员都应该早期学习Gradle:基本使用并不困难。然后始终加入(并熟悉)Apache Commons...永远不要重复发明轮子。 - mike rodent
@mike rodent 错了,从不重新发明轮子是一种盲目的货物崇拜谬论。这正是导致NPM left-pad灾难的原因。本地IO Java库负责很多工作,而达到最终目标所需的少量代码微不足道。https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/ - trilogy

11

自Java 7起,java.nio更受青睐。

import java.nio.file.Files;
import java.nio.file.Paths;

...

Files.createDirectories(Paths.get("a/b/c"));

3

如果您正在使用mkdirs()(如@Zhile Zou所建议的),而您的File对象是文件而不是目录,则可以执行以下操作:

// Create the directory structure
file.getParentFile().mkdirs();

// Create the file
file.createNewFile();

如果你只是使用file.mkdirs(),它会创建一个以文件名命名的文件夹。

2
public static void main(String[] args) {
  File root = new File("C:\\SO");
  List<String> alphabet = new ArrayList<String>();
  for (int i = 0; i < 26; i++) {
    alphabet.add(String.valueOf((char)('a' + i)));
  }

  final int depth = 3;
  mkDirs(root, alphabet, depth);
}

public static void mkDirs(File root, List<String> dirs, int depth) {
  if (depth == 0) return;
  for (String s : dirs) {
    File subdir = new File(root, s);
    subdir.mkdir();
    mkDirs(subdir, dirs, depth - 1);
  }
}

mkDirs 递归地创建一个基于给定的 String 列表的深度为 depth 的目录树,对于 main 来说,该列表由英文字母字符组成。


-1

Scala 代码:

  def makePathRecursive(path: String) = {
    import java.io.File
    import scala.util.{Try, Failure, Success}

    val pathObj = new File(path)
    pathObj.exists match {
      case true => // do nothing
      case false => Try(pathObj.mkdirs) match {
        case Success(_) => // it worked 
        case Failure(e) => // maybe created meanwhile by another thread
          pathObj.exists match { 
          case false => throw new Exception(e)
          case _ =>  
        }
      }
    }
  }

-1
我会编写一个小的实用方法,将起始字母、结束字母和所需深度作为参数传入。该方法会递归调用自身,直到完成:
 private static void createAlphabetFolders(File parent, int start, int end, int deepth){

    if(deepth <= 0){
      return;
    }

    for (int i=start; i < end; i++){

      // create the folder
      String folderName = "" + ((char) i);
      File folder = new File(parent, folderName);
      System.out.println("creating: " + folder.getPath());
      folder.mkdirs();

      // call recursively
      createAlphabetFolders(folder, start, end, deepth-1);
    }
  }

这个可以这样调用:

createAlphabetFolders(new File("abctest"), 'A', 'E', 5);

-2
    // ensures parent directory is created
    File parentFile = destFile.getParentFile();
    if (parentFile != null && !parentFile.exists()) {
        parentFile.mkdirs();
    }

    // creates destination file
    if (!destFile.exists()) {
        destFile.createNewFile();
    }

-2

你可以像这样使用三个循环遍历字符a-z

import java.io.*;

public class FileCreate {

    public static void main(String[] args) throws Exception {
        char trunkDirectory = 'a';
        char branchDirectory = 'a';
        char leaf = 'a';

        while (trunkDirectory != '{') {
            while (branchDirectory != '{') {
                while (leaf != '{') {
                    System.out.println(trunkDirectory + "/" + branchDirectory + "/" + leaf++);
                }
                leaf = 'a';
                branchDirectory++;
            }
            branchDirectory = 'a';
            trunkDirectory++;
        }

    }
}

这只是向控制台输出路径。您可以使用File#mkdirs()来创建递归目录结构,或者在嵌套循环的每个中间部分中创建目录。我会留给您完成。


太聪明了!另一个问题:如果我想限制只使用某些字母,怎么办? - osley
如果子集是连续的,那么起始和结束字符可以很容易地更改。如果它是一组稀疏的字符,那么最好创建一个字符数组,例如 char[] alphabet = {'a','e','i','o','u'}; 并使用类似 for(int i=0;i<alphabet.length;i++) { alphabet[i++]; }; 的索引循环。 - andyb
又来一个未经解释的踩票,距离上次已经两年了! - andyb
还有一个未解释的踩。你们真是最棒的! - andyb

-2

Apache Commons 解决了大部分这些问题。建议尝试使用 -

org.apache.commons.io.FileUtils.forceMkdir(directory);


3
我不认为这是对所提问题的回答。这个单一方法如何实现所要求的功能?这个问题涉及算法,而不是使用哪个API。 - user1531971
1
@jdv,你是怎么确定这个问题是关于算法而不是API的?我在问题本身中没有看到任何这样的描述。 - ABS
"...如何...",但是我的评论实际上是关于单个外部API引用不足以成为一个好的SO答案。 - user1531971
我在6年前回答过这个问题。在不必要地重复之前,请至少阅读以前的答案。 - Rex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接