Java中平台无关路径

84

我知道一个文件的相对路径,并想在Linux和Windows上将其处理为File对象。

在Java中,指定平台无关路径的最佳方法是什么?

8个回答

130

只需使用/。 我已经使用它23.5年了,从未出现过问题。


1
如果我正在使用Java在/opt/template中搜索文件,那么这是否相当于Windows中的c://opt/template? - John Alexander Betts
7
直译:会一直工作,直到出现新的操作系统带来新的奇异路径分隔符为止!甚至在那种情况下,如果JVM可以处理“/”到特定操作系统路径分隔符的转换,则仍然可以工作!因此,“/”通常是一个安全的选择,但使用显式路径分隔符可以未雨绸缪。通俗易懂:这将一直运行,直到有新的操作系统使用新的奇怪路径分隔符为止。即使在这种情况下,如果Java虚拟机可以处理将"/"转换为特定操作系统路径分隔符,则仍然可以正常运行。因此,默认使用"/"是比较安全的选择,但显式地指定路径分隔符可以更好地预防将来可能出现的问题。 - Mohnish
2
@AechoLiu 那只是另一个 Stack Overflow 的答案。并不比这个更具权威性,而这个答案至少是有据可依的。一个正确的引用应该来自 JLS 或 JVM 规范或 Javadoc。 - user207421
1
@EJP 抱歉,我看到了“更新”并在那个SO答案中看到了“现在,我确定我已经看到它有文档记录”的话。所以我相信这应该是正确的。我今天遇到了这个问题,并在SO中找到了答案。你和那个SO答案帮助我解决了这个问题。我只是不想在这个答案中得到任何负评,因为我知道你是正确的。 - AechoLiu
2
其他 Path 类方法使用平台分隔符,因此在 Windows 上,Paths.get("a/b").resolve("c") 将会得到 a/b\c',这将适用于文件打开和其他用例,但在相等性测试中,仍可能导致意外的错误。 - Sipka
显示剩余4条评论

59

File 类包含以下公共成员,可用于处理特定平台的文件路径:

static String pathSeparator:
表示系统相关的路径分隔符,以字符串形式方便使用。
static char pathSeparatorChar:
表示系统相关的路径分隔符。
static String separator:
表示系统相关的默认名称分隔符,以字符串形式方便使用。
static char separatorChar:
表示系统相关的默认名称分隔符。


1
我在我的应用程序中尝试使用pathSeparator,但在OS X上,它是一个冒号(:)。如果你把它扔进文件路径中,OS X会将其解释为文件夹名称内的正斜杠字符。例如:我意外地在用户的home文件夹中创建了一个名为Desktop/foo的文件夹,而不是在用户桌面上创建一个名为foo的文件夹。然而,使用普通的正斜杠(/)可以像预期的那样工作。 - aapierce
36
这个答案需要更好的解释。pathSeparatorpathSeparatorChar是指系统PATH变量中使用的分隔符。问题涉及文件路径,而不是PATH变量。因此,应该使用separatorseparatorChar - RossBille

18

在Java中,您可以使用任何路径分隔符,它将在Unix和Windows上都起作用。 如果您仍然想使用系统路径分隔符,则可以使用File.separator属性,它将根据当前系统给出正确的路径分隔符。

对于根目录,您可以使用listRoots()方法,它会返回一个根目录数组,在Unix系统上只有一个元素,在Windows上则视系统拥有的驱动器数量而定。


pathSeparator 将检索路径之间特定于平台的分隔符(在 Unix 上为 ';',在 Windows 上为 ':')。我认为在这种情况下使用 separator 更合适。 - Jeroen Rosenberg
2
pathSeparator是PATH环境变量中不同条目的分隔符。对于这个问题,File.separator将是正确的选择。 - Thomas Lötzer
3
“在Java中,您可以使用任何路径分隔符,它将在Unix和Windows上都能正常工作。”这是错误的。如果您在Unix上使用反斜杠(\),它将不会被识别为文件路径分隔符,而会被解释为文件名(Unix文件名允许包含反斜杠)。 - Neeme Praks
@ColinHebert 只要涉及到路径分隔符,这个答案就不正确。 - user207421

10
你可以使用静态字段File.separator来获取特定于平台的文件路径分隔符字符。

4

Java 7同样支持在此处使用Paths

通过调用默认FileSystem的getPath方法获取Path。

然后,您可以通过调用以下方法从中获取文件:

File fileSystemObtainedFile = Paths.get("C:\\foo\\bar.txt").toFile();

4

Java在File对象中处理路径很聪明。我只需使用类似于"../foo/bar"的内容,它就可以在这两个平台以及MacOSX上正常工作。


2
只晚了10年...... “无所谓,只需使用'/'”这种说法只有一半是正确的(好吧,三分之一)。你必须考虑数据来自哪里。
如果你在Java中获取路径,它将使用'/'。 如果你在Java中创建路径,它会理解'/'。
但是对于输入到你的程序中的路径呢?
假设我有一系列脚本,用于创建一个配置(Properties)文件。假设其中一个配置变量是INTERESTING_FILE,并且我们生成了包含路径的文件名作为其值。现在假设我想从中提取实际的文件名,我可以这样说:
String[] filename = INTERESTING_FILE.split("/");

这会在Windows系统上出现问题。
String[] filename = INTERESTING_FILE.split(pathSeparator);

这将起作用(通过Paths类清洗它也是如此)。

我想重点是,我不会假设“/”在每种情况下都能正常工作。


并没有真正回答问题。 - james.garriss
2
@NotAJavaGuy建议使用“/”可能会有问题,因为这样你就无法使用“split”来查找文件名。我认为在这里使用“split”才是问题所在。更好的方法是new File(filename).getName() - John

1

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