微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

自从我迁移到Windows 10以来,我的代码一直在特定文件夹, C:UsersTerminalAppDataLocallxssrootfsusrshareterminfo上吐出错误

这个文件夹是特别的,因为它包含小写和大写的名字相同的文件夹,如果小写。

使用windows api读取当前安装的应用程序版本

以编程方式获取上次启动/关机时间

MSOpenTech Redis – 同一台机器上的多个实例

在Windows中运行QT Creator中的项目

基本:在哪里初始化/设置function

问题是我查看了所有的代码库,没有equalsIgnoreCase或toLowerCase或toupperCase实例。

最后,我得出结论, Path.equals返回两个不同的文件夹,这不应该。 这会导致我的代码中出现问题,因为在代码中随处可见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:UsersTerminalAppDataLocallxssrootfsusrshareterminfom is equal to C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM

但是,事实certificate,其他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 am 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:UsersTerminalAppDataLocallxssrootfsusrshareterminfo [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 am folder Has a M folder --- Files in 'm' folder C:UsersTerminalAppDataLocallxssrootfsusrshareterminfom C:UsersTerminalAppDataLocallxssrootfsusrshareterminfomMtxOrb C:UsersTerminalAppDataLocallxssrootfsusrshareterminfomMtxOrb162 C:UsersTerminalAppDataLocallxssrootfsusrshareterminfomMtxOrb204 --- Files in 'M' folder C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoMMtxOrb C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoMMtxOrb162 C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoMMtxOrb204 --- Parent of files in 'm' folder C:UsersTerminalAppDataLocallxssrootfsusrshareterminfom is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfo C:UsersTerminalAppDataLocallxssrootfsusrshareterminfomMtxOrb is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfom C:UsersTerminalAppDataLocallxssrootfsusrshareterminfomMtxOrb162 is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfom C:UsersTerminalAppDataLocallxssrootfsusrshareterminfomMtxOrb204 is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfom --- Parent of files in 'M' folder C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfo C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoMMtxOrb is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoMMtxOrb162 is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoMMtxOrb204 is a child of C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM --- C:UsersTerminalAppDataLocallxssrootfsusrshareterminfom is equal to C:UsersTerminalAppDataLocallxssrootfsusrshareterminfoM

根据文档, Path.equals :

两条path是否相等取决于文件系统的实现。 在某些情况下,path比较不考虑大小写,而其他path则区分大小写。

我怎样才能修复我的代码或JVM,以便Path.equals返回两个不同的文件夹不同的大小写?

如何开发Windows 2008 64位的C#控制台应用程序?

切换RIDEV_CAPTUREMOUSE |时出现奇怪的行为 RIDEV_NOLEGACY

如何将Microsoft Locale ID(LCID)转换为Java中的语言代码或Locale对象

使用python检测鼠标在窗口中的点击

AppleWWDRCA证书需要*用于OpenSSL签名?

对于NTFS中几乎所有的其他位置,Path.equals都是正确的。 但是,“LXSS”文件是使用非正常Windows API(如使用OBJECT_ATTRIBUTES而不指定OBJ_CASE_INSENSITIVE的NtCreateFile )创建的。

如果您在Windows中尝试浏览“M”和“m”,您将注意到只能看到其中一个内容,因为它们显示内容相同。 所以不仅AppData的某些部分难以区分,有些部分平淡无奇,没有一点魔力。

Path::equals的JavaDoc状态:

两条路径是否相等取决于文件系统的实现。 在某些情况下,路径比较不考虑大小写,而其他路径则区分大小写。 这种方法不访问文件系统,文件不需要存在。 如果需要,可以使用isSameFile方法来检查两个路径是否找到同一个文件

由于你的Path没有经过FileSystem测试,所以你应该使用Files :: isSameFile 。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐