草庐IT

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

coder 2024-06-17 原文

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

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

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

问题是我查看了我所有的代码库,它没有 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 - Path.equals() 在 Windows 10 上为两个不同的文件夹(小写 m 和大写 M)返回 true的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  5. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  6. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. ruby-on-rails - ruby 日期方程不返回预期的真值 - 2

    为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998

  10. ruby - 从 String#split 返回的零长度字符串 - 2

    在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"

随机推荐