瞭解 Azure NetApp Files 中的磁碟區語言
Azure NetApp Files 磁碟區上的磁碟區語言(類似於用戶端操作系統的系統地區設定),可在使用 NFS 和 SMB 通訊協定時控制支援的語言和字元集。 Azure NetApp Files 使用 C.UTF-8 的預設磁碟區語言,提供符合 POSIX 規範的 UTF-8 編碼字元集。 C.UTF-8 語言原生支援大小為0-3位元組的字元,其中包括基本多語平面 (BMP) (包括日文、德文和希伯來文和大多數希伯來文和斯拉夫文)上世界上大部分的語言。 如需 BMP 的詳細資訊,請參閱 Unicode。
BMP 以外的字元有時會超過 Azure NetApp Files 所支援的 3 位元組大小。 因此,它們需要使用 Surrogate 配對邏輯,其中會結合多個字元位元組集來形成新的字元。 例如,Emoji 符號屬於此類別,且在未強制執行 UTF-8 的案例中,Azure NetApp Files 支援:例如使用 UTF-16 編碼的 Windows 用戶端或未強制執行 UTF-8 的 NFSv3。 NFSv4.x 會強制執行 UTF-8,這表示使用 NFSv4.x 時,代理字組字元不會正確顯示。
非標準編碼,例如 Shift-JIS 和較不常見的 CJK 字元,在 Azure NetApp Files 中強制執行 UTF-8 時也不會正確顯示。
提示
您應該使用UTF-8傳送和接收文字,以避免無法正確轉譯字元的情況,這可能會導致檔案建立/重新命名或複製錯誤案例。
目前無法在 Azure NetApp Files 中修改磁碟區語言設定。 如需詳細資訊,請參閱 使用特殊字元集的通訊協議行為。
如需最佳做法,請參閱 字元集最佳做法。
Azure NetApp Files NFS 和 SMB 磁碟區中的字元編碼
在 Azure NetApp Files 檔案共享環境中,檔案和資料夾名稱會以使用者讀取和解譯的一系列字元來表示。 這些字元的顯示方式取決於用戶端如何傳送和接收這些字元的編碼方式。 例如,如果用戶端在存取時將舊版 ASCII(美國資訊交換標準代碼) 編碼傳送至 Azure NetApp Files 磁碟區,則僅限於只顯示 ASCII 格式支援的字元。
例如,數據的日文字元為 「已」。 由於此字元無法在 ASCII 中表示,因此使用 ASCII 編碼的用戶端會顯示 “?” 而不是 。
ASCII 僅支援 95 個可列印字元,主要是以英文找到的字元。 每個字元都會使用 1 個字節,這會納入 Azure NetApp Files 磁碟區上的檔案路徑長度 總計。 這會限制數據集的國際化,因為檔名可以有 ASCII 無法辨識的各種字元,從日文到斯拉夫文到表情符號。 國際標準(ISO/IEC 8859)試圖支援更多的國際字元,但也具有其限制。 大部分的新式用戶端會使用某種形式的 Unicode 來傳送和接收字元。
Unicode
由於 ASCII 和 ISO/IEC 8859 編碼的限制,Unicode 標準已建立,因此任何人都可以從其裝置檢視其主區域的語言。
- Unicode 支援超過一百萬個字元集,方法是增加每個字元允許的位元組數目(最多 4 個字節),以及檔案路徑中允許的位元組總數,而不是舊版編碼,例如 ASCII。
- Unicode 支援回溯相容性,方法是保留 ASCII 的前 128 個字元,同時確保前 256 個代碼點與 ISO/IEC 8859 標準相同。
- 在 Unicode 標準中,字元集會細分成平面。 平面是連續群組 65,536 個字碼點。 Unicode 標準共有 17 架飛機(0-16)。 限制為 17,因為 UTF-16 的限制。
- 平面 0 是 基本多語系平面 (BMP) 。 此平面包含多種語言最常使用的字元。
- 在 17 個平面中,目前只有 5 個已指派字元集,從 Unicode 15.1 版起。
- 平面1-17被稱為 補充多語平面(SMP), 並包含較少使用的字元集,例如古寫系統,如村形和象形,以及特殊的中文/日文/韓文(CJK)字元。
- 如需查看字元長度和路徑大小以及控制傳送至系統之編碼的方法,請參閱 將檔案轉換成不同的編碼。
Unicode 使用 Unicode 轉換格式 作為其標準,UTF-8 和 UTF-16 是兩個主要格式。
Unicode 平面
Unicode 利用 17 個 65,536 個字元的平面(256 個字碼點乘以飛機中的 256 個方塊),平面 0 作為 基本多語平面 (BMP) 。 此平面包含多種語言最常使用的字元。 由於世界語言和字元集超過 65536 個字元,因此需要更多平面來支援較不常用的字元集。
例如,第一架飛機(補充多語飛機(SMP)包括歷史劇本,如村形和埃及象形,以及一些奧薩奇,沃朗花旗,阿德拉姆,萬喬和托托。 平面 1 也包含一些符號和 圖釋 字元。
平面 2 – 補充表觀平面 (SIP) - 包含中日/韓文 (CJK) 統一表意。 平面 1 和 2 中的字元通常大小為 4 個字節。
例如:
- 平面 1 中的「大眼睛笑臉」表情符號 「😃大小為 4 位元元。
- 1 平面中的埃及象形 「𓀀」 大小為 4 個字節。
- 平面 1 中的 Osage 字元 「𐒸」 大小為 4 個字節。
- 平面 2 中的 CJK 字元 「𫝁」 大小為 4 個字節。
由於這些字元的大小都是 >3 個字節,因此需要使用代理字組才能正常運作。 Azure NetApp Files 原生支援代理組,但字元的顯示會因使用的通訊協定、客戶端的地區設定和遠端用戶端存取應用程式的設定而有所不同。
UTF-8
UTF-8 使用 8 位編碼,最多可以有 1,112,064 個字碼點(或字元)。 UTF-8 是 Linux 作業系統中所有語言的標準編碼方式。 由於 UTF-8 使用 8 位編碼,因此可能的不帶正負號整數上限為 255 (2^8 – 1),這也是該編碼的最大檔名長度。 UTF-8 用於因特網上超過 98% 的頁面,使其成為迄今為止採用最採用的編碼標準。 Web 超文本應用程式技術工作組(WHATWG)認為 UTF-8 是「所有 [文字] 的強制編碼方式,基於安全性考慮,瀏覽器應用程式不應該使用 UTF-16。
UTF-8 格式的字元各使用 1 到 4 個字節,但幾乎所有語言中的字元都會使用 1 到 3 個字節。 例如:
- 拉丁字母 “A” 使用 1 個字節。 (128個保留的 ASCII 字元之一)
- 著作權符號 “©” 使用 2 個字節。
- 字元 “ä” 使用 2 個字節。 (1 位元組代表 “a” + 1 位元組代表 umlaut)
- 數據的日文漢字元號會使用3個字節。
- 笑臉表情符號 (😃) 使用 4 個字節。
語言地區設定可以使用計算機標準 UTF-8 (C.UTF-8) 或更 特定的區域格式,例如en_US。UTF-8,ja.UTF-8 等在盡可能存取 Azure NetApp Files 時,您應該使用 Linux 用戶端的 UTF-8 編碼。 從OS X開始,macOS 用戶端也會使用UTF-8進行預設編碼,而且不應該調整。
Windows 用戶端使用UTF-16。 在大部分情況下,此設定應保留為OS地區設定的預設值,但較新的用戶端會透過複選框提供UTF-8字元的Beta支援。 您也可以調整 Windows 中的終端客戶端,視需要在 PowerShell 或 CMD 中使用 UTF-8。 如需詳細資訊,請參閱 具有特殊字元集的雙重通訊協議行為。
UTF-16
UTF-16 使用 16 位編碼,而且能夠編碼 Unicode 的所有 1,112,064 個字碼點。 UTF-16 的編碼方式可以使用一或兩個 16 位程式代碼單位,每個 2 個字節的大小。 UTF-16 中的所有字元都使用 2 或 4 位元元組大小。 UTF-16 中使用 4 個字節的字元會利用 Surrogate 字組,結合兩個不同的 2 位元組字元來建立新的字元。 這些補充字元落在標準 BMP 平面之外,並進入其他多語系飛機的其中一個。
UTF-16 用於 Windows 作業系統和 API、Java 和 JavaScript。 因為它不支援與 ASCII 格式的回溯相容性,因此在網路上從未受到歡迎。 UTF-16 隻佔因特網上所有頁面的 0.002% 左右。 Web 超文本應用程式技術工作組(WHATWG)認為 UTF-8 是「所有文字的強制編碼」,並建議應用程式不要使用 UTF-16 進行瀏覽器安全性。
Azure NetApp Files 支援大部分的 UTF-16 字元,包括代理字組。 如果不支援字元,Windows 用戶端會回報「您指定的檔名無效或太長」的錯誤。
透過遠端客戶端處理的字元集
您可以設定遠端連線至掛接 Azure NetApp Files 磁碟區的用戶端(例如 Linux 用戶端的 SSH 連線以存取 NFS 掛接),以傳送和接收特定的磁碟區語言編碼。 透過遠端連線公用程式傳送至客戶端的語言編碼可控制如何建立和檢視字元集。 因此,使用與另一個遠端連線不同語言編碼的遠端連線(例如兩個不同的 PuTTY 視窗)在列出 Azure NetApp Files 磁碟區中的檔案和資料夾名稱時,可能會顯示字元的不同結果。 在大部分情況下,這不會建立差異(例如拉丁/英文字元),但在特殊字元的情況下,例如 emoji,結果可能會有所不同。
例如,針對遠端連線使用UTF-8編碼會顯示 Azure NetApp Files 磁碟區中字元的可預測結果,因為 C.UTF-8 是磁碟區語言。 「數據」(數據)的日文字符會根據終端機所傳送的編碼方式而有所不同。
PuTTY 中的字元編碼
當 PuTTY 視窗使用 UTF-8 時(在 Windows 的翻譯設定中找到),此字元會針對 Azure NetApp Files 中掛接的 NFSv3 磁碟區正確表示:
如果 PuTTY 視窗使用不同的編碼方式,例如 ISO-8859-1:1998(拉丁-1、西歐),即使檔名相同,相同的字元仍會以不同的方式顯示。
PuTTY 預設不包含 CJK 編碼。 有 修補程式可用來 將這些語言集新增至 PuTTY。
Bastion 中的字元編碼
Microsoft Azure 建議使用 Bastion 對 Azure 中的虛擬機器 (VM) 進行遠端連線。 使用 Bastion 時,傳送和接收的語言編碼不會在設定中公開,但會利用標準 UTF-8 編碼。 因此,使用UTF-8在PuTTY中看到的大部分字元集也應該顯示在 Bastion 中,前提是所使用的通訊協定支援字元集。
提示
您可以使用其他 SSH 終端機,例如 TeraTerm。 TeraTerm 預設提供更廣泛的支援字元集,包括 CJK 編碼和非標準編碼,例如 Shift-JIS。
具有特殊字元集的通訊協議行為
Azure NetApp Files 磁碟區使用 UTF-8 編碼,並原生支持不超過 3 個字節的字元。 ASCII 和 UTF-8 集合中的所有字元都會正確顯示,因為它們落在 1 到 3 位元組的範圍中。 例如:
- 拉丁字母字元 “A” 使用 1 個字節(128 個保留的 ASCII 字元之一)。
- 著作權符號©使用 2 個字節。
- 字元 “ä” 會針對 “a” 使用 2 個字節(1 個字節,而 umlaut 則使用 1 個字節)。
- 數據的日文漢字元號會使用3個字節。
Azure NetApp Files 也支援透過 Surrogate 配對邏輯超過 3 個字節的字元(例如 emoji),前提是用戶端編碼和通訊協定版本支持它們。 如需通訊協議行為的詳細資訊,請參閱:
SMB 行為
在SMB磁碟區中,Azure NetApp Files 會針對任何可從SMB用戶端存取的檔案或目錄建立和維護兩個名稱:原始長名稱,並以8.3格式的名稱。
使用 Azure NetApp Files 在 SMB 中的檔名
當檔案或目錄名稱超過允許的字元位元組或使用不支援的字元時,Azure NetApp Files 會產生 8.3 格式的名稱,如下所示:
- 它會截斷源檔或目錄名稱。
- 它會將波浪線 (~) 和數位 (1-5) 附加至在截斷之後不再是唯一的檔案或目錄名稱。 如果有超過五個檔案具有非唯一名稱,Azure NetApp Files 會建立與原始名稱無關的唯一名稱。 針對檔案,Azure NetApp Files 會將擴展名截斷為三個字元。
例如,如果 NFS 用戶端建立名為 specifications.html
的檔案,Azure NetApp Files 會以 8.3 格式建立檔名 specif~1.htm
。 如果此名稱已經存在,Azure NetApp Files 會在檔名結尾使用不同的數位。 例如,如果 NFS 用戶端接著建立另 specifications\_new.html
一個名為 的檔案,則的 8.3 格式 specifications\_new.html
為 specif~2.htm
。
SMB 中搭配 Azure NetApp Files 的特殊字元
搭配 Azure NetApp Files 磁碟區使用 SMB 時,由於代理組支援,允許在檔案和資料夾名稱中使用的超過 3 個字節的字元(包括圖釋)。 以下是 Windows 檔案總管在搭配預設 UTF-16 編碼使用英文時,從 Windows 用戶端建立之資料夾上 BMP 以外的字元所見。
注意
Windows 檔案總管中的預設字型是 Segoe UI。 字型變更可能會影響用戶端上某些字元的顯示方式。
用戶端上的字元顯示方式取決於系統字型和語言和地區設定。 一般而言,不論編碼是否為UTF-8或UTF-16,所有通訊協定都支援屬於 BMP的字元。
使用 CMD 或 PowerShell 時,字元集檢視可能會取決於字型設定。 這些公用程式預設有有限的字型選擇。 CMD 使用 Consolas 做為預設字型。
檔名可能不會如預期般顯示,取決於某些控制台原本不支援 Segoe UI 或其他正確轉譯特殊字元的字型。
此問題可以使用PowerShell ISE 在 Windows 用戶端上解決,以提供更健全的字型支援。 例如,將 PowerShell ISE 設定為 Segoe UI 時,會正確顯示具有支援字元的檔名。
不過,PowerShell ISE 是專為腳本設計,而不是管理共用。 較新的 Windows 版本提供 Windows 終端機,可讓您控制字型和編碼值。
如果磁碟區已啟用雙通訊協定(NFS 和 SMB),您可能會觀察到不同的行為。 如需詳細資訊,請參閱 具有特殊字元集的雙重通訊協議行為。
NFS 行為
NFS 顯示特殊字元的方式取決於所使用的 NFS 版本、用戶端的地區設定、安裝的字型,以及使用中遠端連線客戶端的設定。 例如,使用 Bastion 存取 Ubuntu 用戶端時,可能會處理與相同 VM 上設定為不同地區設定的 PuTTY 用戶端不同的字元。 隨後的 NFS 範例會依賴 Ubuntu VM 的這些地區設定:
~$ locale
LANG=C.UTF-8
LANGUAGE=
LC\_CTYPE="C.UTF-8"
LC\_NUMERIC="C.UTF-8"
LC\_TIME="C.UTF-8"
LC\_COLLATE="C.UTF-8"
LC\_MONETARY="C.UTF-8"
LC\_MESSAGES="C.UTF-8"
LC\_PAPER="C.UTF-8"
LC\_NAME="C.UTF-8"
LC\_ADDRESS="C.UTF-8"
LC\_TELEPHONE="C.UTF-8"
LC\_MEASUREMENT="C.UTF-8"
LC\_IDENTIFICATION="C.UTF-8"
LC\_ALL=
NFSv3 行為
NFSv3 不會對檔案和資料夾強制執行 UTF 編碼。 在大部分情況下,特殊字元集應該沒有任何問題。 不過,所使用的連線用戶端可能會影響傳送和接收字元的方式。 例如,針對 Azure 連線用戶端 Bastion 中的資料夾名稱使用 BMP 外部的 Unicode 字元,可能會導致一些非預期的行為,因為用戶端編碼的運作方式。
在下列螢幕快照中,Bastion 無法在透過NFSv3 為目錄命名時,從瀏覽器外部複製並貼上值至 CLI 提示字元。 嘗試複製並貼上 的值 NFSv3Bastion𓀀𫝁😃𐒸
時,特殊字元會在輸入中顯示為引號。
允許透過 NFSv3 複製貼上命令,但字元會建立為其數值,因而影響其顯示:
NFSv3Bastion'$'\262\270\355\240\214\355\260\200\355\241\255\355\275\201\355\240\275\355\270\203\355\240\201\355
此顯示是因為 Bastion 在複製和貼上時用來傳送文字值的編碼。
使用 PuTTY 在 NFSv3 上建立具有相同字元的資料夾時,該資料夾名稱與 Bastion 中用來建立資料夾的名稱不同。 圖釋會顯示如預期般顯示(由於已安裝的字型和地區設定),但其他字元(如 Osage “𐒸”) 則不會。
從 PuTTY 視窗中,字元會顯示正確:
NFSv4.x 行為
NFSv4.x 會根據 RFC-8881 國際化規格,在檔案和資料夾名稱中強制執行 UTF-8 編碼。
因此,如果以非UTF-8編碼方式傳送特殊字元,NFSv4.x 可能不會允許此值。
在某些情況下,可以使用基本多語平面 (BMP) 以外的字元來允許命令,但在建立之後可能不會顯示值。
例如,以資料夾名稱發出mkdir
,包括字元 “𓀀𫝁𐒸😃” (補充多語平面 (SMP) 和補充表像平面 (SIP) 中的字元似乎在 NFSv4.x 中成功。 執行 命令時 ls
,不會顯示資料夾。
root@ubuntu:/NFSv4/NFS$ mkdir "NFSv4 Putty 𓀀𫝁😃𐒸"
root@ubuntu:/NFSv4/NFS$ ls -la
total 8
drwxrwxr-x 3 nobody 4294967294 4096 Jan 10 17:15 .
drwxrwxrwx 4 root root 4096 Jan 10 17:15 ..
root@ubuntu:/NFSv4/NFS$
資料夾存在於磁碟區中。 變更為隱藏的目錄名稱可從 PuTTY 用戶端運作,而且可以在該目錄內建立檔案。
root@ubuntu:/NFSv4/NFS$ cd "NFSv4 Putty 𓀀𫝁😃𐒸"
root@ubuntu:/NFSv4/NFS/NFSv4 Putty 𓀀𫝁😃𐒸$ sudo touch Unicode.txt
root@ubuntu:/NFSv4/NFS/NFSv4 Putty 𓀀𫝁😃𐒸$ ls -la
-rw-r--r-- 1 root root 0 Jan 10 17:31 Unicode.txt
來自 PuTTY 的統計資料命令也會確認資料夾存在:
root@ubuntu:/NFSv4/NFS$ stat "NFSv4 Putty 𓀀𫝁😃𐒸"
**File: NFSv4 Putty** **𓀀**** 𫝁 ****😃**** 𐒸**
Size: 4096 Blocks: 8 IO Block: 262144 **directory**
Device: 3ch/60d Inode: 101 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-01-10 17:15:44.860775000 +0000
Modify: 2024-01-10 17:31:35.049770000 +0000
Change: 2024-01-10 17:31:35.049770000 +0000
Birth: -
即使已確認資料夾存在,通配符命令仍無法運作,因為客戶端無法正式「查看」顯示中的資料夾。
root@ubuntu:/NFSv4/NFS$ cp \* /NFSv3/
cp: can't stat '\*': No such file or directory
NFSv4.1 會在遇到不依賴 UTF-8 編碼的字元時,將錯誤傳送給用戶端。
例如,使用 Bastion 嘗試存取我們透過 NFSv4.1 使用 PuTTY 建立的相同目錄時,結果是:
root@ubuntu:/NFSv4/NFS$ cd "NFSv4 Putty 𓀀𫝁😃�"
-bash: cd: $'NFSv4 Putty \262\270\355\240\214\355\260\200\355\241\255\355\275\201\355\240\275\355\270\203\355\240\201\355': Invalid argument
The "invalid argument" error message doesn't help diagnose the root cause, but a packet capture shines a light on the problem:
78 1.704856 y.y.y.y x.x.x.x NFS 346 V4 Call (Reply In 79) LOOKUP DH: 0x44caa451/NFSv4 Putty ��������
79 1.705058 x.x.x.x y.y.y.y NFS 166 V4 Reply (Call In 25) OPEN Status: NFS4ERR\_INVAL
由於可以從 PuTTY 存取資料夾(因為傳送和接收編碼),所以如果指定了名稱,就可以複製該資料夾。 將該資料夾從 NFSv4.1 Azure NetApp Files 磁碟區複製到 NFSv3 Azure NetApp Files 磁碟區之後,資料夾名稱會顯示:
root@ubuntu:/NFSv4/NFS$ cp -r /NFSv4/NFS/"NFSv4 Putty 𓀀𫝁😃𐒸" /NFSv3/NFSv3/
root@ubuntu:/NFSv4/NFS$ ls -la /NFSv3/NFSv3 | grep v4
drwxrwxr-x 2 root root 4096 Jan 10 17:49 NFSv4 Putty 𓀀𫝁😃𐒸
如果嘗試將檔案轉換成非 UTF-8 格式,例如 Shift-JIS,就可以看到相同的NFS4ERR\_INVAL
錯誤。
# echo "Test file with SJIS encoded filename" \> "$(echo 'テストファイル.txt' | iconv -t SJIS)"
-bash: $(echo 'テストファイル.txt' | iconv -t SJIS): Invalid argument
如需詳細資訊,請參閱 將檔案轉換成不同的編碼。
雙重通訊協議行為
Azure NetApp Files 允許 NFS 和 SMB 透過雙重通訊協定存取來存取磁碟區。 由於 NFS (UTF-8) 和 SMB (UTF-16) 所使用的語言編碼差異很大,字元集、檔案和資料夾名稱,以及路徑長度在通訊協定之間可能會有非常不同的行為。
從 SMB 檢視 NFS 建立的檔案和資料夾
當 Azure NetApp Files 用於雙重通訊協定存取時(SMB 和 NFS),UTF-16 不支援的字元集可能會用於透過 NFS 使用 UTF-8 所建立的檔名。 在這些情況下,當SMB存取具有不支援字元的檔案時,會使用 8.3簡短檔名慣例在SMB中截斷名稱。
使用字元集建立的 NFSv3 檔案和 SMB 行為
NFSv3 不會強制執行UTF-8編碼。 使用非標準語言編碼的字元(例如 Shift-JIS)在使用 NFSv3 時,會使用 Azure NetApp Files。
在下列範例中,使用 Unicode 中不同平面的不同字元集的一系列資料夾名稱是使用 NFSv3 在 Azure NetApp Files 磁碟區中建立的。 從 NFSv3 檢視時,這些會顯示正確。
root@ubuntu:/NFSv3/dual$ ls -la
drwxrwxr-x 2 root root 4096 Jan 10 19:43 NFSv3-BMP-English
drwxrwxr-x 2 root root 4096 Jan 10 19:43 NFSv3-BMP-Japanese-German-資ä
drwxrwxr-x 2 root root 4096 Jan 10 19:43 NFSv3-BMP-copyright-©
drwxrwxr-x 2 root root 4096 Jan 10 19:44 NFSv3-CJK-plane2-𫝁
drwxrwxr-x 2 root root 4096 Jan 10 19:44 NFSv3-emoji-plane1-😃
從 Windows SMB 中,BMP 中找到字元的資料夾會正確顯示,但由於 UTF-8/UTF-16 轉換與這些字元不相容,該平面以外的字元會以 8.3 名稱格式顯示。
具有字元集的 NFSv4.1 建立檔案和 SMB 行為
在上述範例中,名為 NFSv4 Putty 𓀀𫝁😃𐒸
的資料夾是在 Azure NetApp Files 磁碟區上透過 NFSv4.1 建立,但無法使用 NFSv4.1 來檢視。 不過,您可以使用SMB來查看。 由於從 NFS 用戶端建立的不支援字元集,以及不同 Unicode 平面中字元的不相容 UTF-8/UTF-16 轉換,所以 SMB 的名稱會截斷為支援的 8.3 格式。
當資料夾名稱使用 BMP 中找到的標準UTF-8字元時,SMB 會正確翻譯名稱。
root@ubuntu:/NFSv4/NFS$ mkdir NFS-created-English
root@ubuntu:/NFSv4/NFS$ mkdir NFS-created-資ä
root@ubuntu:/NFSv4/NFS$ ls -la
total 16
drwxrwxr-x 5 nobody 4294967294 4096 Jan 10 18:26 .
drwxrwxrwx 4 root root 4096 Jan 10 17:15 ..
**drwxrwxr-x 2 root root 4096 Jan 10 18:21 NFS-created-English**
**drwxrwxr-x 2 root root 4096 Jan 10 18:26 NFS-created-**** 資 ****ä**
透過 NFS 建立 SMB 的檔案和資料夾
Windows 用戶端是用來存取 SMB 共用的主要客戶端類型。 這些客戶端預設為 UTF-16 編碼。 在區域設定中啟用 UTF-8 編碼字元,就可以在 Windows 中支援某些 UTF-8 編碼字元:
在 Azure NetApp Files 中透過 SMB 共用建立檔案或資料夾時,字元集會使用編碼為 UTF-16。 因此,使用UTF-8編碼的用戶端(例如以Linux為基礎的NFS用戶端)可能無法正確轉譯某些字元集,特別是落在 基本多語平面 (BMP) 以外的字元。
不支援的字元行為
在這些案例中,當 NFS 用戶端存取使用 SMB 建立且不支援字元的檔案時,名稱會顯示為代表字元 Unicode 值的一系列數值。
例如,此資料夾是在 Windows 檔案總管中使用 BMP 以外的字元建立的。
PS Z:\SMB\> dir
Directory: Z:\SMB
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/9/2024 9:53 PM SMB𓀀𫝁😃𐒸
透過 NFSv3,SMB 建立的資料夾會顯示:
$ ls -la
drwxrwxrwx 2 root daemon 4096 Jan 9 21:53 'SMB'$'\355\240\214\355\260\200\355\241\255\355\275\201\355\240\275\355\270\203\355\240\201\355\262\270'
透過 NFSv4.1,SMB 建立的資料夾如下所示:
$ ls -la
drwxrwxrwx 2 root daemon 4096 Jan 4 17:09 'SMB'$'\355\240\214\355\260\200\355\241\255\355\275\201\355\240\275\355\270\203\355\240\201\355\262\270'
支援的字元行為
當字元位於 BMP 中時,SMB 和 NFS 通訊協定及其版本之間沒有任何問題。
例如,在 Azure NetApp Files 磁碟區上使用 SMB 建立的資料夾名稱,在 BMP 中可跨多種語言找到字元(英文、德文、斯拉夫文、Runic)顯示所有通訊協定和版本。
- 基本拉丁文 “SMB”
- 希臘 文 “Ͷ^”
- 斯拉夫文 “ЁЄЊ”
- Runic “ᚠᚱᛯ”
- CJK 兼容性表意字 “豈滑虜”
這就是名稱出現在SMB中的方式:
PS Z:\SMB\> mkdir SMBͶΘΩЁЄЊᚠᚱᛯ豈滑虜
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/11/2024 8:00 PM SMBͶΘΩЁЄЊᚠᚱᛯ豈滑虜
這是從 NFSv3 顯示名稱的方式:
$ ls | grep SMBͶΘΩЁЄЊᚠᚱᛯ豈滑虜
SMBͶΘΩЁЄЊᚠᚱᛯ豈滑虜
這是從 NFSv4.1 顯示名稱的方式:
$ ls /NFSv4/SMB | grep SMBͶΘΩЁЄЊᚠᚱᛯ豈滑虜
SMBͶΘΩЁЄЊᚠᚱᛯ豈滑虜
將檔案轉換成不同的編碼方式
檔案和資料夾名稱不是使用語言編碼之檔系統物件的唯一部分。 檔案內容(例如文本檔內的特殊字元)也可以發揮作用。 例如,如果嘗試以不相容格式以特殊字元儲存檔案,可能會看到錯誤訊息。 在此情況下,無法將具有 Katagana 字元的檔案儲存在 ANSI 中,因為這些字元不存在於該編碼中。
一旦該檔案以該格式儲存,字元就會轉換成問號:
您可以從 NAS 用戶端檢視檔案編碼。 在 Windows 用戶端上,您可以使用 記事本 或 記事本++ 之類的應用程式來檢視檔案的編碼方式。 如果在用戶端上安裝 Windows 子系統 Linux 版 (WSL) 或 Git,file
則可以使用 命令。
這些應用程式也可讓您藉由儲存為不同的編碼類型來變更檔案的編碼方式。 此外,PowerShell 可用來使用 和 Set-Content
Cmdlet 來轉換檔案Get-Content
上的編碼方式。
例如,檔案 utf8-text.txt
會編碼為UTF-8,並包含 BMP 以外的字元。 因為使用UTF-8,因此字元會正確顯示。
如果編碼轉換成UTF-32,字元就不會正確顯示。
PS Z:\SMB\> Get-Content .\utf8-text.txt |Set-Content -Encoding UTF32 -Path utf32-text.txt
Get-Content
也可以用來顯示檔案內容。 根據預設,PowerShell 會使用 UTF-16 編碼(代碼頁 437)和控制台的字型選擇受到限制,因此無法正確顯示具有特殊字元的 UTF-8 格式檔案:
Linux 用戶端可以使用 file
命令來檢視檔案的編碼方式。 在雙重通訊協議環境中,如果使用SMB建立檔案,則使用NFS的Linux用戶端可以檢查檔案編碼方式。
$ file -i utf8-text.txt
utf8-text.txt: text/plain; charset=utf-8
$ file -i utf32-text.txt
utf32-text.txt: text/plain; charset=utf-32le
您可以使用 命令,在 Linux 用戶端 iconv
上執行檔案編碼轉換。 若要檢視支援的編碼格式清單,請使用 iconv -l
。
例如,UTF-8 編碼的檔案可以轉換成 UTF-16。
$ iconv -t UTF16 utf8-text.txt \> utf16-text.txt
$ file -i utf8-text.txt
utf8-text.txt: text/plain; **charset=utf-8**
$ file -i utf16-text.txt
utf16-text.txt: text/plain; **charset=utf-16le**
如果目的地編碼不支援檔案名稱或檔案內容上的字元集,則不允許轉換。 例如,Shift-JIS 無法支援檔案內容中的字元。
$ iconv -t SJIS utf8-text.txt SJIS-text.txt
iconv: illegal input sequence at position 0
如果檔案具有編碼所支援的字元,則轉換將會成功。 例如,如果檔案包含 Katagana 字元テストファイル,則 Shift-JIS 轉換會成功超過 NFS。 由於此處使用的NFS用戶端不會因為地區設定而瞭解Shift-JIS,因此編碼會顯示“unknown-8bit”。
$ cat SJIS.txt
テストファイル
$ file -i SJIS.txt
SJIS.txt: text/plain; charset=utf-8
$ iconv -t SJIS SJIS.txt \> SJIS2.txt
$ file -i SJIS.txt
SJIS.txt: text/plain; **charset=utf-8**
$ file -i SJIS2.txt
SJIS2.txt: text/plain; **charset=unknown-8bit**
因為 Azure NetApp Files 磁碟區只支援 UTF-8 相容的格式,因此 Katagana 字元會轉換成無法讀取的格式。
$ cat SJIS2.txt
▒e▒X▒g▒t▒@▒C▒▒
使用 NFSv4.x 時,即使 NFSv4.x 強制執行 UTF-8 編碼,在檔案內容中存在不相容的字元時,還是允許轉換。 在此範例中,位於 Azure NetApp Files 磁碟區上具有 Katagana 字元的 UTF-8 編碼檔案會正確顯示檔案的內容。
$ file -i SJIS.txt
SJIS.txt: text/plain; charset=utf-8
S$ cat SJIS.txt
テストファイル
但是一旦轉換,檔案中的字元就會因為編碼不相容而顯示不正確。
$ cat SJIS2.txt
▒e▒X▒g▒t▒@▒C▒▒
如果檔案的名稱包含 UTF-8 不支援的字元,則轉換會透過 NFSv3 成功,但因為通訊協定版本的 UTF-8 強制執行而故障轉移 NFSv4.x。
# echo "Test file with SJIS encoded filename" \> "$(echo 'テストファイル.txt' | iconv -t SJIS)"
-bash: $(echo 'テストファイル.txt' | iconv -t SJIS): Invalid argument
字元集最佳做法
在 Azure NetApp Files 磁碟區上使用標準 基本多語平面 (BMP) 以外的特殊字元或字元時,應該考慮一些最佳做法。
- 由於 Azure NetApp Files 磁碟區使用 UTF-8 磁碟區語言,因此 NFS 用戶端的檔案編碼也應該使用 UTF-8 編碼來取得一致的結果。
- 檔名中的字元集或包含在檔案內容中的字元集應該與適當顯示和功能相容 UTF-8。
- 由於SMB使用UTF-16字元編碼,因此 BMP以外的字元可能無法在雙通訊協定磁碟區中的NFS上正確顯示。 盡可能將檔案內容中特殊字元的使用降到最低。
- 避免在檔名中使用 BMP 以外的特殊字元,特別是在使用NFSv4.1 或雙通訊協定磁碟區時。
- 對於不在 BMP 中的字元集,使用單一檔案通訊協定時,UTF-8 編碼應該允許在 Azure NetApp Files 中顯示字元(僅限 SMB 或僅限 NFS)。 不過,在大部分情況下,雙通訊協定磁碟區無法容納這些字元集。
- Azure NetApp Files 磁碟區不支援非標準編碼(例如 Shift-JIS)。
- Azure NetApp Files 磁碟區支援 Surrogate 字組字元(例如 emoji)。