2017-04-13 63 views
0

我一直在stackoverflow.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」,還是我錯過了什麼?

+0

的最佳答案:文件名中的一個包含Unicode字符,只是看起來相同作爲ANSI字符。 –

+0

謝謝,根據我的更新#1(重命名測試通過慢慢截斷名稱然後重建它),這確實是這種情況。我將再次報告有關此:) – Lori

+0

我剛剛[在超級用戶上發佈了答案](https://超級用戶。com/a/1199537/96662)顯示了一種方法,讓您準確查看文件名中的哪些代碼點。 –

回答

1

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 

==> 
相關問題