的Windows/NTFS:两个文件在同一目录中相同的长的名字?
我一直在*.com一个潜伏者多年(伟大的网站,在这里用户),但从来没有需要问一个问题。现在是时候了:-)让我开始:的Windows/NTFS:两个文件在同一目录中相同的长的名字?
操作系统:x64 Windows 8.0到Windows 10(15063.14)(这个问题存在多年,但我从来没有完全追求它,所以我们可以排除它是具体到特定的Windows版本)
FS:NTFS
问题:2个文件在同一目录相同(长)的名字,我想不通这是怎么都不可能发生。每当我手动升级我的电子邮件客户端时,都会发生这种情况。它的主要.EXE文件(MailClient.exe)永远不会要求替换,如果将新文件复制到同一个目录。相反,它们都放在那里,名字完全一样。
问题无关与特定的目录,我可以绕在NTFS目录开车到新创建的两个.EXE文件拷贝没有问题(还没有得到“覆盖”的问题存在)。
让我告诉你:
C:\temp\2>dir
Volume in drive C is SSD 840 Pro
Volume Serial Number is 0C6D-D489
Directory of C:\temp\2
13.04.2017 02:29 <DIR> .
13.04.2017 02:29 <DIR> ..
21.10.2016 17:10 24.742.760 MailClient.exe
27.12.2016 03:26 24.911.872 MailCliеnt.exe
2 File(s) 49.654.632 bytes
2 Dir(s) 78.503.038.976 bytes free
但是,如果做一个DIR/X,这出现:
C:\temp\2>dir /x
Volume in drive C is SSD 840 Pro
Volume Serial Number is 0C6D-D489
Directory of C:\temp\2
13.04.2017 02:29 <DIR> .
13.04.2017 02:29 <DIR> ..
21.10.2016 17:10 24.742.760 MAILCL~2.EXE MailClient.exe
27.12.2016 03:26 24.911.872 MAILCL~1.EXE MailCliеnt.exe
2 File(s) 49.654.632 bytes
2 Dir(s) 78.503.038.976 bytes free
所以他们显然有不同的8.3名,OK,但确切同样的长名。这是另一种情况的截图。这两个文件都在Windows“属性”对话框中显示相同的位置(右键单击)。不幸的是,我不允许发布图像(看起来) - 只是尝试。所以你必须接受我的话。
我无法弄清楚这是怎么可能的,而这正在扰乱我;)一旦我将这两个文件重命名为例如1.exe,Windows就会开始告诉我,在同一目录中已经有一个具有该名称的文件。因此很明显有事情做与文件名,但他们都完全相同,没有多余的空格,什么都没有,你可以从DIR命令看到。
我也尝试重命名它们,并手动重写两个字符的确切字词“MailCient.exe”,以确保字符是相同的,Windows仍然不会抱怨,它们都会一次去那里再次以相同的名字。然而,重命名他们“MAIL.EXE”和“MAIL.EXE”都不行,那么Windows是说,与该名称的另一个文件已经存在。但是,将它们都命名为“MailClient.exe”就绝对没问题,没有Windows的抱怨。
这个另一个有趣的事实,如果我DIR为mailclient.exe直接,出现这种情况:
C:\temp\2>dir mailclient.exe
Volume in drive C is SSD 840 Pro
Volume Serial Number is 0C6D-D489
Directory of C:\temp\2
21.10.2016 17:10 24.742.760 MailClient.exe
1 File(s) 24.742.760 bytes
0 Dir(s) 78.501.998.592 bytes free
但是,如果找的* .exe,出现这种情况:
C:\temp\2>dir *.exe
Volume in drive C is SSD 840 Pro
Volume Serial Number is 0C6D-D489
Directory of C:\temp\2
21.10.2016 17:10 24.742.760 MailClient.exe
27.12.2016 03:26 24.911.872 MailCliеnt.exe
2 File(s) 49.654.632 bytes
0 Dir(s) 78.501.990.400 bytes free
这产生同样有趣的结果:
C:\temp\2>ren mailclient.exe *.bak
C:\temp\2>dir
Volume in drive C is SSD 840 Pro
Volume Serial Number is 0C6D-D489
Directory of C:\temp\2
13.04.2017 02:50 <DIR> .
13.04.2017 02:50 <DIR> ..
21.10.2016 17:10 24.742.760 MailClient.bak
27.12.2016 03:26 24.911.872 MailCliеnt.exe
2 File(s) 49.654.632 bytes
2 Dir(s) 78.501.990.400 bytes free
再换:
C:\temp\2>ren mailclient.bak MailClient.exe
C:\temp\2>dir
Volume in drive C is SSD 840 Pro
Volume Serial Number is 0C6D-D489
Directory of C:\temp\2
13.04.2017 02:51 <DIR> .
13.04.2017 02:51 <DIR> ..
21.10.2016 17:10 24.742.760 MailClient.exe
27.12.2016 03:26 24.911.872 MailCliеnt.exe
2 File(s) 49.654.632 bytes
2 Dir(s) 78.501.982.208 bytes free
从来就还检查该文件的权限和所有权了,它改变不了什么。另外我已经清除了NTFS日志,甚至是事务日志+运行chkdsk,它也没有显示任何错误。
关于这种神秘情况的任何想法?我错过了什么?
非常感谢:)
更新#1:
从来就只是尝试这样做:将Windows资源管理器,并通过截取他们的名字重新命名后,对方这两个文件。所以我首先将第一个“MailClient.exe”重命名为“MailClien.exe”,然后将秒“MailClient.exe”重命名为“MailClien.exe”。同样,没有消息通过Windows,他们有相同的名称,它只是改名都罚款。然后我继续“MailClie.exe”。工作。 但是,只要我试图重命名为“MailCli.exe”,Windows就会抱怨,并告诉我,已经有另一个名称为该文件的文件。试图从那里重新命名为“MailClient.exe”也不起作用,仅仅对于其中一个,因为那时Windows说(并且正确)以至于具有该名称的文件已经存在。所以它似乎归结为两个文件名中可能具有另一个ANSI字符的“e”?然而,我不知道另一个“e”,还是我错过了什么?
Harry Johnston is right:文件名的一个包含Unicode字符,只是看起来同一个ANSI字符。
阅读Naming Files, Paths, and Namespaces:
在较新的文件系统,如NTFS,exFAT的,UDF和FAT32时,Windows在磁盘上 存储长文件名的Unicode,这意味着 原长文件名始终保留。即使 长文件名包含扩展字符也是如此,无论代码 在磁盘读取或写入操作期间处于活动状态。
使用下面的PowerShell脚本43381802b.ps1
检测和显示非ANSI文件名(见下文不同的调用):
param([string[]]$Path = '.',
[switch]$Cpp, ### list any non-ANSI character in file names like a C++ literal
### i.e. a prefix \u followed by a four digit Unicode code point
[switch]$All ### list all files including pure ANSI-encoded file names
)
Set-StrictMode -Version latest
$strArr = Get-ChildItem -path $Path
$arrDiff = @()
for ($i=0; $i -lt $strArr.Count; $i++) {
$strDiff = 'ANSI'
$strName = ''
$auxName = $strArr[$i].Name
for ( $k=0; $k -lt $auxName.Length; $k++) {
if ([int][char]$auxName[$k] -gt 255) {
$strDiff = 'UCS2'
$strName += '\u{0:X4}' -f [int][char]$auxName[$k]
} else {
$strName += $auxName[$k]
}
}
if ($All.IsPresent -or $strDiff -eq 'UCS2') {
$strArr[$i] | Add-Member NoteProperty Code $strDiff
$strArr[$i] | Add-Member NoteProperty CppName $strName
$arrDiff += $strArr[$i]
}
}
if ($Cpp.IsPresent) {
$arrDiff | Select-Object -Property Code, Mode, LastWriteTime, Length, CppName | ft
} else {
$arrDiff | Select-Object -Property Code, Mode, LastWriteTime, Length, Name | ft
}
输出:
PS D:\PShell> .\SO\43381802b.ps1 'C:\testC\43381802'
Code Mode LastWriteTime Length Name
---- ---- ------------- ------ ----
UCS2 -a---- 02/05/2017 11:47:53 317 MailCliеnt.txt
UCS2 -a---- 02/05/2017 11:49:04 317 МailClient.txt
UCS2 -a---- 02/05/2017 11:50:16 399 МailCliеnt.txt
PS D:\PShell> .\SO\43381802b.ps1 'C:\testC\43381802' -Cpp
Code Mode LastWriteTime Length CppName
---- ---- ------------- ------ -------
UCS2 -a---- 02/05/2017 11:47:53 317 MailCli\u0435nt.txt
UCS2 -a---- 02/05/2017 11:49:04 317 \u041CailClient.txt
UCS2 -a---- 02/05/2017 11:50:16 399 \u041CailCli\u0435nt.txt
PS D:\PShell> .\SO\43381802b.ps1 'C:\testC\43381802' -Cpp -All
Code Mode LastWriteTime Length CppName
---- ---- ------------- ------ -------
ANSI -a---- 02/05/2017 11:44:05 235 MailClient.txt
UCS2 -a---- 02/05/2017 11:47:53 317 MailCli\u0435nt.txt
UCS2 -a---- 02/05/2017 11:49:04 317 \u041CailClient.txt
UCS2 -a---- 02/05/2017 11:50:16 399 \u041CailCli\u0435nt.txt
使用以下43381802a.ps1
脚本获取有关非ANSI字符的更多信息(请参阅下面的第一个调用)以及它们在文件名中的位置(请参见后面的调用,请使用-Detail
开关):
param( [string[]] $strArr = @('ΗGreek', 'НCyril', 'HLatin'),
[switch]$Detail)
Set-StrictMode -Version latest
$auxArr = @()
if ((Get-Command -Name Get-CharInfo -ErrorAction SilentlyContinue) -and
(-not $Detail.IsPresent)) {
$auxArr = $strArr | Get-CharInfo |
Where-Object { [int]$_.Codepoint.Replace('U+', '0x') -ge 128 }
} else {
foreach ($strStr in $strArr) {
for ($i = 0; $i -lt $strStr.Length; $i++) {
if ([int][char]$strStr[$i] -ge 128) {
$auxArr += [PSCustomObject] @{
Char = $strStr[$i]
CodePoint = 'U+{0:x4}' -f [int][char]$strStr[$i]
Category = $i + 1 ### 1-based index
Description = $strStr ### string itself
}
}
}
}
}
$auxArr
输出:
PS D:\PShell> .\SO\43381802a.ps1 (Get-childitem -path 'C:\testC\43381802').Name
Char CodePoint Category Description
---- --------- -------- -----------
е U+0435 LowercaseLetter Cyrillic Small Letter Ie
М U+041C UppercaseLetter Cyrillic Capital Letter Em
М U+041C UppercaseLetter Cyrillic Capital Letter Em
е U+0435 LowercaseLetter Cyrillic Small Letter Ie
PS D:\PShell> .\SO\43381802a.ps1 (Get-childitem -path 'C:\testC\43381802').Name -detail
Char CodePoint Category Description
---- --------- -------- -----------
е U+0435 8 MailCliеnt.txt
М U+041c 1 МailClient.txt
М U+041c 1 МailCliеnt.txt
е U+0435 8 МailCliеnt.txt
测试上的文件:
==> dir /-C /X /A-D C:\testC\43381802\
Volume in drive C has no label.
Volume Serial Number is …
Directory of C:\testC\43381802
02/05/2017 11:44 235 MAILCL~1.TXT MailClient.txt
02/05/2017 11:47 317 MAILCL~2.TXT MailCliеnt.txt
02/05/2017 11:49 317 AILCLI~1.TXT МailClient.txt
02/05/2017 11:50 399 AILCLI~2.TXT МailCliеnt.txt
4 File(s) 1268 bytes
0 Dir(s) 69914857472 bytes free
==>
的最佳答案:文件名中的一个包含Unicode字符,只是看起来相同作为ANSI字符。 –
谢谢,根据我的更新#1(重命名测试通过慢慢截断名称然后重建它),这确实是这种情况。我将再次报告有关此:) – Lori
我刚刚[在超级用户上发布了答案](https://超级用户。com/a/1199537/96662)显示了一种方法,让您准确查看文件名中的哪些代码点。 –