GetCanonicalPath和toRealPath之间的差异
是否存在File.getCanonicalPath()和File.toPath().toRealPath()会产生不同结果的情况?
他们似乎都做了非常相似的事情,但文档从来没有明确表示他们应该做同样的事情。
在边界案例中,我是否倾向于使用其中一种方法?
那么File.getAbsoltePath()和Path.toAbsoltePath()又如何呢--它们应该以相同的方式工作吗?
解决方案
结论:
getAbsolutePath
和getPath
从不失败,因为它们不进行验证getCanonicalPath
URL中的驱动器号无效或与当前文件夹不同时得出无效结果toPath().toRealPath()
正在检查有效性,但该文件需要存在,并且还可以跟随或不跟随符号链接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:tarGetu0000Suffix", "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:homeaiserworkestfs arGet..Target)
F-CAN: Success(D:homeaiserworkestfs arget)
P-TO: Success(d:tarGet..Target)
P-ABS: Success(D:homeaiserworkestfs arGet..Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:homeaiserworkestfsTarget)
P-ABS-NOR: Success(D:homeaiserworkestfsTarget)
P-REAL: Success(D:homeaiserworkestfs arget)
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:homeaiserworkestfs arGet..Target...)
F-CAN: Success(D:homeaiserworkestfs)
P-TO: Success(d:tarGet..Target...)
P-ABS: Success(D:homeaiserworkestfs arGet..Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeaiserworkestfs)
P-ABS-NOR: Success(D:homeaiserworkestfs)
P-REAL: Success(D:homeaiserworkestfs)
Use: d:tarGet
on-existent....Target... -> Relative path contains non-existent file
F-GET: Success(d:tarGet
on-existent....Target...)
F-ABS: Success(d:homeaiserworkestfs arGet
on-existent....Target...)
F-CAN: Success(D:homeaiserworkestfs)
P-TO: Success(d:tarGet
on-existent....Target...)
P-ABS: Success(D:homeaiserworkestfs arGet
on-existent....Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeaiserworkestfs)
P-ABS-NOR: Success(D:homeaiserworkestfs)
P-REAL: Success(D:homeaiserworkestfs)
Use: d:target\file -> Double slash
F-GET: Success(d:targetfile)
F-ABS: Success(d:homeaiserworkestfs argetfile)
F-CAN: Success(D:homeaiserworkestfs argetfile)
P-TO: Success(d:targetfile)
P-ABS: Success(D:homeaiserworkestfs argetfile)
P-NOR: Success(d:targetfile)
P-NOR-ABS: Success(D:homeaiserworkestfs argetfile)
P-ABS-NOR: Success(D:homeaiserworkestfs argetfile)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:homeaiserworkestfs argetfile)
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: arGet..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: arGet..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:homeaiserworkestfsza:tarGet..Target...)
F-CAN: Success(D:homeaiserworkestfs)
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:homeaiserworkestfs arGet|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)
相关文章