How to combine paths in Java?
C#/。NET中是否有
此静态方法将一个或多个字符串组合到路径中。
而不是让所有内容都基于字符串,您应该使用旨在表示文件系统路径的类。
如果您使用的是Java 7或Java 8,则应强烈考虑使用
1 | Path path = Paths.get("foo","bar","baz.txt"); |
如果需要满足Java-7之前的环境,可以使用
1 2 3 |
如果以后希望将其作为字符串返回,则可以调用
1 2 3 4 5 6 |
在Java 7中,应使用
1 | Path newPath = path.resolve(childPath); |
尽管NIO2 Path类对于使用不必要的不??同API的File似乎有点多余,但实际上它更优雅,更强大。
请注意,
Note that while this method is very convenient, using it will imply an assumed reference to the default FileSystem and limit the utility of the calling code. Hence it should not be used in library code intended for flexible reuse. A more flexible alternative is to use an existing Path instance as an anchor, such as:
1
2 Path dir = ...
Path path = dir.resolve("file");
1 | Path childPath = path.relativize(newPath); |
主要的答案是使用File对象。但是Commons IO确实有一个类FilenameUtils可以执行这种操作,例如concat()方法。
自从乔恩(Jon)的原始答案以来,我就已经知道了很长时间,但是我对OP有类似的要求。
通过扩展Jon的解决方案,我提出了以下内容,它将采用一个或多个路径段,而您可以将其扔给它。
用法
1 2 3 | Path.combine("/Users/beardtwizzle/"); Path.combine("/","Users","beardtwizzle"); Path.combine(new String[] {"/","Users","beardtwizzle","arrayUsage" }); |
在这里为其他有类似问题的人编码
1 2 3 4 5 6 7 8 9 10 11 12 |
平台无关的方法(使用File.separator,即能否工作取决于运行代码的操作系统:
1 2 3 4 5 6 7 8 9 10 | java.nio.file.Paths.get(".","path","to","file.txt") // relative unix path: ./path/to/file.txt // relative windows path: .\path\to\filee.txt java.nio.file.Paths.get("/","path","to","file.txt") // absolute unix path: /path/to/filee.txt // windows network drive path: \\path\to\file.txt java.nio.file.Paths.get("C:","path","to","file.txt") // absolute windows path: C:\path\to\file.txt |
为了增强JodaStephen的答案,Apache Commons IO具有FilenameUtils来执行此操作。示例(在Linux上):
1 | assert org.apache.commons.io.FilenameUtils.concat("/home/bob","work\\stuff.log") =="/home/bob/work/stuff.log" |
它是独立于平台的,可以生成系统所需的任何分隔符。
如果您不需要的只是字符串,则可以使用com.google.common.io.Files
1 | Files.simplifyPath("some/prefix/with//extra///slashes" +"file//name") |
要得到
1 | "some/prefix/with/extra/slashes/file/name" |
这在Java 8中也适用:
1 2 | Path file = Paths.get("Some path"); file = Paths.get(file +"Some other path"); |
也许聚会晚了,但是我想分享我对此的看法。我正在使用Builder模式,并允许方便地链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public class Files { public static class PathBuilder { private File file; private PathBuilder ( File root ) { file = root; } private PathBuilder ( String root ) { file = new File(root); } public PathBuilder append ( File more ) { file = new File(file, more.getPath()) ); return this; } public PathBuilder append ( String more ) { file = new File(file, more); return this; } public File buildFile () { return file; } } public static PathBuilder buildPath ( File root ) { return new PathBuilder(root); } public static PathBuilder buildPath ( String root ) { return new PathBuilder(root); } } |
用法示例:
1 2 3 4 5 6 7 8 |
生成的
1 | /hello/world/warez.lha |
甚至:
1 | A:\hello\world\warez.lha |
这是处理多个路径部分和边缘条件的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
该解决方案提供了一个接口,用于连接String []数组中的路径片段。它使用java.io.File.File(String parent,String child):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public static joinPaths(String[] fragments) { String emptyPath =""; return buildPath(emptyPath, fragments); } private static buildPath(String path, String[] fragments) { if (path == null || path.isEmpty()) { path =""; } if (fragments == null || fragments.length == 0) { return""; } int pathCurrentSize = path.split("/").length; int fragmentsLen = fragments.length; if (pathCurrentSize <= fragmentsLen) { String newPath = new File(path, fragments[pathCurrentSize - 1]).toString(); path = buildPath(newPath, fragments); } return path; } |
然后,您可以执行以下操作:
返回值:
1 | "/dir/anotherDir/filename.txt" |