java - Path.equals() 在 Windows 10 上为两个不同的文件夹(小写 m 和大写 M)返回 true

标签 java windows java-8 windows-10 windows-subsystem-for-linux

我创建了一个文件索引器,它在 Windows 7 和 Ubuntu 中运行良好。

自从我迁移到 Windows 10 后,我的代码一直在特定文件夹上出现错误,C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo

这个文件夹很特别,因为它包含具有小写和大写名称的文件夹,如果小写则相同。

screenshot of folder

问题是我查看了我所有的代码库,它没有 equalsIgnoreCasetoLowerCasetoUpperCase 的实例。

最后我得出结论,Path.equals 为两个不同的文件夹返回 true,这是不应该的。这会导致我的代码出现问题,因为 Path 被用作代码中到处都是 Map 的键,特别是在我的索引器实现中,这会导致 Collectors .groupingBy 将属于不同文件夹的文件分组到同一文件夹中:

    Map<Path, List<DetailedFileReference>> parentFolderToDetailList = finderResult.getDetails().stream()
            .collect(Collectors.groupingBy(o -> o.asPathObject().getParent()));

我能够弄清楚复制步骤:

Path originFolder = Paths.get("C:\\Users\\Terminal\\AppData\\Local\\lxss\\rootfs\\usr\\share\\terminfo");
Path lowercaseFolder = originFolder.resolve("m");
Path uppercaseFolder = originFolder.resolve("M");

if (lowercaseFolder.equals(uppercaseFolder)) {
    System.out.println(lowercaseFolder.toString() + " is equal to " + uppercaseFolder.toString());
}

此代码打印:

C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m is equal to C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M

然而,事实证明其他 Java 代码确实看到了这两个文件夹之间的区别,因为 Files.walk 工作正常:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public final class DuplicateFileIndexing {
    public static void main(String[] args) throws IOException {
        Path originFolder = Paths.get("C:\\Users\\Terminal\\AppData\\Local\\lxss\\rootfs\\usr\\share\\terminfo");
        Path lowercaseFolder = originFolder.resolve("m");
        Path uppercaseFolder = originFolder.resolve("M");

        System.out.println(originFolder.toAbsolutePath().toString());

        List<String> directoriesInOriginFolder = Files.walk(originFolder, 1)
                .filter(path -> Files.isDirectory(path))
                .map(path -> path.getFileName().toString())
                .collect(Collectors.toList());
        System.out.println(directoriesInOriginFolder);

        if (directoriesInOriginFolder.contains("m")) {
            System.out.println("Has a m folder");
        }
        if (directoriesInOriginFolder.contains("M")) {
            System.out.println("Has a M folder");
        }

        System.out.println("---");

        System.out.println("Files in 'm' folder");
        Files.walk(lowercaseFolder, 1)
                .map(path -> path.toAbsolutePath().toString())
                .forEach(System.out::println);

        System.out.println("---");

        System.out.println("Files in 'M' folder");
        Files.walk(uppercaseFolder, 1)
                .map(path -> path.toAbsolutePath().toString())
                .forEach(System.out::println);

        System.out.println("---");

        System.out.println("Parent of files in 'm' folder");
        Files.walk(lowercaseFolder, 1)
                .map(path -> path.toAbsolutePath().toString() + " is a child of " + path.getParent().toString())
                .forEach(System.out::println);

        System.out.println("---");

        System.out.println("Parent of files in 'M' folder");
        Files.walk(uppercaseFolder, 1)
                .map(path -> path.toAbsolutePath().toString() + " is a child of " + path.getParent().toString())
                .forEach(System.out::println);

        System.out.println("---");

        if (lowercaseFolder.equals(uppercaseFolder)) {
            System.out.println(lowercaseFolder.toString() + " is equal to " + uppercaseFolder.toString());
        }
    }
}

这打印:

C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo
[terminfo, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, a, b, c, d, E, e, f, g, h, i, j, k, L, l, M, m, N, n, o, P, p, Q, q, r, s, t, u, v, w, X, x, z]
Has a m folder
Has a M folder
---
Files in 'm' folder
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m\MtxOrb
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m\MtxOrb162
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m\MtxOrb204
---
Files in 'M' folder
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M\MtxOrb
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M\MtxOrb162
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M\MtxOrb204
---
Parent of files in 'm' folder
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m\MtxOrb is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m\MtxOrb162 is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m\MtxOrb204 is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m
---
Parent of files in 'M' folder
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M\MtxOrb is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M\MtxOrb162 is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M\MtxOrb204 is a child of C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M
---
C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\m is equal to C:\Users\Terminal\AppData\Local\lxss\rootfs\usr\share\terminfo\M

根据文档,Path.equals :

Whether or not two path are equal depends on the file system implementation. In some cases the paths are compared without regard to case, and others are case sensitive.

如何修复我的代码或 JVM,以便 Path.equals 为两个大小写不同的文件夹返回 false?


最佳答案

Path::equals 的 JavaDoc 指出:

Whether or not two path are equal depends on the file system implementation. In some cases the paths are compared without regard to case, and others are case sensitive. This method does not access the file system and the file is not required to exist. Where required, the isSameFile method may be used to check if two paths locate the same file.

由于您的Path 没有针对FileSystem 进行测试,您应该使用Files::isSameFile .

关于java - Path.equals() 在 Windows 10 上为两个不同的文件夹(小写 m 和大写 M)返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43571659/

相关文章:

java - 三叉树实现错误

c - 接收不同MAC地址的数据包

java - Java 8 中的::(双冒号)运算符

lambda - 使用 Stream api 对多个变量进行减少和分配

java - 如何使用时区偏移格式化 LocalDateTime

java - 如何将多个带有标签的面板添加到单个框架中?

java - JodaTime 向下舍入到最接近的一刻钟

java - Spring MVC 表单验证日期字段

c++ "GetThreadTimes"但分辨率更高

windows - Windows 7 和 Windows 8(台式机/Metro)之间的 Internet Explorer 10 有何不同?