0

我有一个LinkedHashSet如下String

Set<String> dirSet = new LinkedHashSet<String>();

上面有12个String元素Set如下:

root/dir1/dir2/dir3/dir4/dir5/baseDir1/
root/dir1/dir2/dir3/dir4/dir5/baseDir1/subDir/
root/dir1/dir2/dir3/dir4/dir5/baseDir2/
root/dir1/dir2/dir3/dir4/dir5/baseDir2/subDir/
root/dir1/dir2/dir3/dir4/dir5/baseDir3/
root/dir1/dir2/dir3/dir4/dir5/baseDir3/subDir/
root/dir1/dir2/dir3/dir4/dir5/baseDir4/
root/dir1/dir2/dir3/dir4/dir5/baseDir4/subDir/
root/dir1/dir2/dir3/dir4/dir5/baseDir5/
root/dir1/dir2/dir3/dir4/dir5/baseDir5/subDir/
root/dir1/dir2/dir3/dir4/dir5/baseDir6/
root/dir1/dir2/dir3/dir4/dir5/baseDir6/subDir/

我想编写一个方法来迭代上面Set的方法,该方法的输出是String Array包含创建上述目录结构的命令。

输出String Array应包含String以下元素:

mkdir root/
mkdir root/dir1/
mkdir root/dir1/dir2/
mkdir root/dir1/dir2/dir3/
mkdir root/dir1/dir2/dir3/dir4/
mkdir root/dir1/dir2/dir3/dir4/dir5/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir1/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir1/subDir/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir2/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir2/subDir/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir3/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir3/subDir/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir4/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir4/subDir/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir5/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir5/subDir/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir6/
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir6/subDir/

我能够达到dir5水平,然后baseDir1/subDir/通过迭代 Set 并借助String.split()方法来创建令牌,直到达到一个水平。

但是,当我再次必须升级时(baseDir2、baseDir3 等),我无法解决问题。

我怎样才能做到这一点?

谢谢阅读!

4

3 回答 3

1

您需要使用 mkdirs 而不是 mkdir:

http://docs.oracle.com/javase/1.4.2/docs/api/java/io/File.html#mkdirs()

于 2013-09-06T14:33:44.077 回答
0

如果您的意思是mkdirunix 命令,那么您可以作弊并使用mkdir -p它来创建必要的父目录。

mkdir -p root/dir1/dir2/dir3/dir4/dir5/baseDir1/
mkdir -p root/dir1/dir2/dir3/dir4/dir5/baseDir1/subDir/

等等。或者只是在 Java 中创建目录,使用File.mkdirs()它做同样的事情。

要回答实际问题,我会使用中间结构,例如TreeSet

TreeSet<String> mkdirCmds = new TreeSet<String>();
for(String origPath : dirSet) {
  if(origPath.endsWith("/")) {
    // strip trailing slash if there is one
    origPath = origPath.substring(0, origPath.length() - 1);
  }
  mkdirCmds.add("mkdir " + origPath);
  int lastSlash = origPath.lastIndexOf('/');
  while(lastSlash >= 0) {
    mkdirCmds.add("mkdir " + origPath.substring(0, lastSlash));
    lastSlash = origPath.lastIndexOf('/', lastSlash - 1);
  }
}
String[] result = mkdirCmds.toArray(new String[0]);

这将为您mkdir提供所有原始路径及其父母、祖父母等的命令列表,没有重复(因为mkdirCmds是一个集合)并且父母在他们的孩子之前列出(因为TreeSet<String>按字典顺序排序)。

对于您的原始输入,它将产生

mkdir root
mkdir root/dir1
mkdir root/dir1/dir2
mkdir root/dir1/dir2/dir3
mkdir root/dir1/dir2/dir3/dir4
mkdir root/dir1/dir2/dir3/dir4/dir5
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir1
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir1/subDir
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir2
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir2/subDir
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir3
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir3/subDir
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir4
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir4/subDir
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir5
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir5/subDir
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir6
mkdir root/dir1/dir2/dir3/dir4/dir5/baseDir6/subDir
于 2013-09-06T14:31:48.433 回答
0

这将起作用,

List<String> list = Arrays.asList(
"root/dir1/dir2/dir3/dir4/dir5/baseDir1/",
"root/dir1/dir2/dir3/dir4/dir5/baseDir1/subDir/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir2/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir2/subDir/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir3/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir3/subDir/",
"root/dir1/dir2/dir3/dir4/dir5/baseDir4/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir4/subDir/",
"root/dir1/dir2/dir3/dir4/dir5/baseDir5/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir5/subDir/", 
"root/dir1/dir2/dir3/dir4/dir5/baseDir6/",
"root/dir1/dir2/dir3/dir4/dir5/baseDir6/subDir/");

Set<String> dirSet = new LinkedHashSet<>(list); 
Set<Path> allDirs = new LinkedHashSet<>();
for (String file : dirSet) {
    recur(allDirs, Paths.get(file));
} 

for (Path path : allDirs) {
    System.out.println("mkdir " + path);
}

...

public static void recur(Set<Path> paths, Path path) {
    if (path == null)
        return;
    recur(paths, path.getParent());
    paths.add(path);
}

使用递归方法。如果Path传递的对象null在其父对象上重复出现,则返回。然后添加路径。

因为我们使用LinkedHashSet保留顺序的 a,所以添加的第一个路径将是 the 的root目录,Path然后是它的每个子目录。你也可以用一个TreeSet

它打印

mkdir root
mkdir root\dir1
mkdir root\dir1\dir2
mkdir root\dir1\dir2\dir3
mkdir root\dir1\dir2\dir3\dir4
mkdir root\dir1\dir2\dir3\dir4\dir5
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir1
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir1\subDir
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir2
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir2\subDir
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir3
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir3\subDir
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir4
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir4\subDir
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir5
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir5\subDir
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir6
mkdir root\dir1\dir2\dir3\dir4\dir5\baseDir6\subDir

您可以随时根据需要订购它们。Path也可能有内部排序逻辑。

于 2013-09-06T14:44:17.197 回答