gpt4 book ai didi

java - getCanonicalPath 和 toRealPath 之间的区别

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:43:14 28 4
gpt4 key购买 nike

是否存在 File.getCanonicalPath() 和 File.toPath().toRealPath() 会产生不同结果的情况?他们似乎都做了相当相似的事情,但文档从未真正说明他们应该做同样的事情。是否存在我更喜欢一种方法而不是另一种方法的边界情况?File.getAbsolutePath() 与 Path.toAbsolutePath() 又如何 - 它们应该以相同的方式工作吗?

最佳答案

结论:

  • getAbsolutePathgetPath 永远不会失败,因为它们不进行验证
  • getCanonicalPath 当来自 url 的盘符无效或与当前文件夹不同时得到无效结果
  • toPath().toRealPath() 正在检查有效性但文件需要存在并且也可以跟随或不跟随符号链接(symbolic link)
  • toPath() 足够安全,不需要文件存在。
  • .toPath().toAbsolutePath().normalize() 是最好的,不需要文件存在

我在windows下对@John做过类似的测试

  @Test
public void testCanonical() throws IOException {
test("d:tarGet\\..\\Target", "File exist and drive letter is on the current one");
test("d:tarGet\\..\\Target\\.\\..\\", "File exist and drive letter is on the current one, but parent of current drive should exist");
test("d:tarGet\\non-existent\\..\\..\\Target\\.\\..\\", "Relative path contains non-existent file");
test("d:target\\\\file", "Double slash");
test("c:tarGet\\..\\Target\\.", "File doesn't exist and drive letter is on different drive than the current one");
test("l:tarGet\\..\\Target\\.\\..\\", "Drive letter doesn't exist");
test("za:tarGet\\..\\Target\\.\\..\\", "Drive letter is double so not valid");
test("d:tarGet|Suffix", "Path contains invalid chars in windows (|)");
test("d:tarGet\u0000Suffix", "Path contains invalid chars in both linux and windows (\\0)");
}

private void test(String filename, String message) throws IOException {
java.io.File file = new java.io.File(filename);
System.out.println("Use: " + filename + " -> " + message);
System.out.println("F-GET: " + Try.of(() -> file.getPath()));
System.out.println("F-ABS: " + Try.of(() -> file.getAbsolutePath()));
System.out.println("F-CAN: " + Try.of(() -> file.getCanonicalPath()));
System.out.println("P-TO: " + Try.of(() -> file.toPath()));
System.out.println("P-ABS: " + Try.of(() -> file.toPath().toAbsolutePath()));
System.out.println("P-NOR: " + Try.of(() -> file.toPath().normalize()));
System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
System.out.println("P-REAL: " + Try.of(() -> file.toPath().toRealPath()));
System.out.println("");
}

结果是:

Use:  d:tarGet\..\Target -> File exist and drive letter is on the current one
F-GET: Success(d:tarGet\..\Target)
F-ABS: Success(d:\home\raiser\work\restfs\tarGet\..\Target)
F-CAN: Success(D:\home\raiser\work\restfs\target)
P-TO: Success(d:tarGet\..\Target)
P-ABS: Success(D:\home\raiser\work\restfs\tarGet\..\Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:\home\raiser\work\restfs\Target)
P-ABS-NOR: Success(D:\home\raiser\work\restfs\Target)
P-REAL: Success(D:\home\raiser\work\restfs\target)

Use: d:tarGet\..\Target\.\..\ -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET: Success(d:tarGet\..\Target\.\..)
F-ABS: Success(d:\home\raiser\work\restfs\tarGet\..\Target\.\..)
F-CAN: Success(D:\home\raiser\work\restfs)
P-TO: Success(d:tarGet\..\Target\.\..)
P-ABS: Success(D:\home\raiser\work\restfs\tarGet\..\Target\.\..)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:\home\raiser\work\restfs\)
P-ABS-NOR: Success(D:\home\raiser\work\restfs)
P-REAL: Success(D:\home\raiser\work\restfs)

Use: d:tarGet\non-existent\..\..\Target\.\..\ -> Relative path contains non-existent file
F-GET: Success(d:tarGet\non-existent\..\..\Target\.\..)
F-ABS: Success(d:\home\raiser\work\restfs\tarGet\non-existent\..\..\Target\.\..)
F-CAN: Success(D:\home\raiser\work\restfs)
P-TO: Success(d:tarGet\non-existent\..\..\Target\.\..)
P-ABS: Success(D:\home\raiser\work\restfs\tarGet\non-existent\..\..\Target\.\..)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:\home\raiser\work\restfs\)
P-ABS-NOR: Success(D:\home\raiser\work\restfs)
P-REAL: Success(D:\home\raiser\work\restfs)

Use: d:target\\file -> Double slash
F-GET: Success(d:target\file)
F-ABS: Success(d:\home\raiser\work\restfs\target\file)
F-CAN: Success(D:\home\raiser\work\restfs\target\file)
P-TO: Success(d:target\file)
P-ABS: Success(D:\home\raiser\work\restfs\target\file)
P-NOR: Success(d:target\file)
P-NOR-ABS: Success(D:\home\raiser\work\restfs\target\file)
P-ABS-NOR: Success(D:\home\raiser\work\restfs\target\file)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:\home\raiser\work\restfs\target\file)

Use: c:tarGet\..\Target\. -> File doesn't exist and drive letter is on different drive than the current one
F-GET: Success(c:tarGet\..\Target\.)
F-ABS: Success(c:\\tarGet\..\Target\.)
F-CAN: Success(C:\Target)
P-TO: Success(c:tarGet\..\Target\.)
P-ABS: Success(C:\tarGet\..\Target\.)
P-NOR: Success(c:Target)
P-NOR-ABS: Success(C:\Target)
P-ABS-NOR: Success(C:\Target)
P-REAL: Failure(java.nio.file.NoSuchFileException: C:\Target)

Use: l:tarGet\..\Target\.\..\ -> Drive letter doesn't exist
F-GET: Success(l:tarGet\..\Target\.\..)
F-ABS: Success(l:\tarGet\..\Target\.\..)
F-CAN: Success(L:\)
P-TO: Success(l:tarGet\..\Target\.\..)
P-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR: Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL: Failure(java.io.IOException: Unable to get working directory of drive 'L')

Use: za:tarGet\..\Target\.\..\ -> Drive letter is double so not valid
F-GET: Success(za:tarGet\..\Target\.\..)
F-ABS: Success(D:\home\raiser\work\restfs\za:tarGet\..\Target\.\..)
F-CAN: Success(D:\home\raiser\work\restfs)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet\..\Target\.\..)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet\..\Target\.\..)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet\..\Target\.\..)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet\..\Target\.\..)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet\..\Target\.\..)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet\..\Target\.\..)

Use: d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET: Success(d:tarGet|Suffix)
F-ABS: Success(d:\home\raiser\work\restfs\tarGet|Suffix)
F-CAN: Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)

关于java - getCanonicalPath 和 toRealPath 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30920623/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com