3

在使用某些 File 对象时,我遇到了我认为不寻常的行为。

import java.io.File;

public class MyClass
{
    public static void main(String[] args)
    {
        File file = new File("C:\\x..");

        System.out.println(file.isDirectory());

        System.out.println(file.listFiles());
    }
}

假设C:\x存在某个目录,file.isDirectory()将在路径末尾添加两个点返回 true。这复制了命令行中的行为,cd x..将目录更改为x.

但是,当调用 时file.listFiles(),该方法返回 null,这仅在文件不是目录时才应该发生。这似乎与 . 的定义不一致listFiles()

为什么会这样?为什么路径末尾有两个点会转到同一个目录,就好像没有点一样?

这个问题似乎是 Windows 独有的。Linux 正确 (?) 为isDirectory().

4

2 回答 2

4

Windows 从路径和文件名中修剪尾随点。我无法找到具体的参考,这只是一直如此的神秘事物之一。

它从完整路径名中修剪尾随点,而不是单个组件。

因此,虽然 "C:\x...." 与 "C:\x" 相同,但 "C:\x....\filename" 与 "C:\x\filename" 不同,因为后者没有尾随点。

您必须FileSystem在 Windows 上查看 JDK 的本机源代码,才能准确了解它是如何获取文件列表的,但我怀疑它正在使用 Windows 进行某种搜索,例如“C:\x..\*.*” FindFirstFileAPI调用或其他东西,点不再尾随。换句话说,假设“C:\x”是一个目录,而路径“C:\x..”是一个目录,“C:\x..\*.*”不匹配,而“C:\ x..\subdirectory”不映射到“C:\x\subdirectory”。

您应该避免使用此类路径。我不确定您最初是如何获得该路径字符串的。

您可以使用File.getCanonicalPath()File.getCanonicalFile()将其转换回更有用的路径名。

顺便说一句,如果您想在 Windows 中获得一些乐趣,请在命令提示符下键入以下内容(假设“c:\windows\temp”存在,否则替换为其他路径):

echo > \\?\c:\windows\temp\x.

Windows 中的\\?\前缀禁用文件名处理和扩展。现在删除生成的文件。也可以在 Explorer 中尝试。

剧透:

您必须使用控制台中的通配符将其删除,例如del x?

于 2013-11-07T07:26:35.910 回答
-1

..你忘了在它应该是之前添加额外的斜杠c:\\x\\..。这将指出你C:确实

于 2013-11-07T07:18:58.687 回答