Tại sao Windows 7 hoạt động với Unicode mà không phải với UTF-8?
Thuật ngữ
Unicode và UTF-8 không giống nhau: Unicode là một bộ ký tự xác định một bộ ký tự (một tiết mục) và gán các số (điểm mã) cho mỗi ký tự đó. UTF 8 là một trong một số mã hóa có thể được sử dụng để thể hiện một luồng các ký tự Unicode trên đĩa hoặc trong truyền. Ví dụ, cùng một dòng các ký tự Unicode cũng có thể được mã hóa thành UTF ‑ 16, UTF ‑ 32 hoặc UTF 7.
Tuy nhiên, Notepad Mời bạn "mã hóa" tùy chọn bao gồm ANSI
, Unicode
, Unicode big-endian
và UTF-8
. Các nhà phát triển Microsoft đã viết điều này đã sử dụng các thuật ngữ sai. Khi họ nói "Unicode", rất có thể họ có nghĩa là " UTF-16
little endian ". Khi họ nói "ANSI", họ có nghĩa là Mã Trang 1252 (CP-1252).
Microsoft Notepad
Tôi tin rằng Notepad của Microsoft ghi UTF-16 bằng dấu thứ tự byte ( BOM ) và Notepad tìm BOM khi đọc tệp văn bản. BOM thông báo cho ứng dụng rằng tệp là UTF-16 và cho biết liệu đó là endian lớn hay endian nhỏ.
Nếu Notepad không tìm thấy BOM, nó sẽ gọi hàm thư viện IsTextUnicode
, xem dữ liệu và cố gắng đoán mã hóa nào đã được sử dụng. Đôi khi (chắc chắn) nó đoán không chính xác. Đôi khi, nó đoán rằng tệp "ANSI" là "Unicode". Cố gắng diễn giải tệp UTF-16 hoặc UTF-8 dưới dạng Mã Trang 1252 sẽ khiến nó hiển thị các glyph sai và không thể tìm thấy glyph để hiển thị một số giá trị 8 bit - những giá trị này sẽ được hiển thị dưới dạng hình vuông.
Như harrymc nói trong câu trả lời của mình , có những lựa chọn thay thế tốt hơn cho Notepad. Nhưng Notepad cho phép bạn chọn mã hóa một cách rõ ràng khi mở tệp (thay vì để Notepad để đoán).
Dấu hiệu đặt hàng Byte
Theo tập đoàn Unicode, Dấu thứ tự Byte (BOM) là tùy chọn. Tuy nhiên, Windows dựa vào các BOM để phân biệt giữa một số mã hóa.
Vì vậy, trong ngắn hạn, có thể các tập tin của bạn thiếu BOM vì một số lý do? Có lẽ BOM đã bị mất đôi khi trong quá trình nâng cấp?
Nếu bạn vẫn có các tệp gốc hiển thị dưới dạng hình vuông, bạn có thể tạo một kết xuất hex của chúng để xem chúng có chứa BOM không.
Tiêu chuẩn tệp văn bản thuần túy
Vấn đề là có hiệu quả không - không có tiêu chuẩn phổ quát cho các tập tin văn bản đơn giản. Thay vào đó chúng tôi có một số không tương thích và chưa biết.
Làm thế nào có kết thúc dòng được đánh dấu? Một số nền tảng sử dụng tính năng Vận chuyển trở lại ký tự điều khiển (CR) theo sau là Line Feed (LF), một số sử dụng CR một mình và một số sử dụng một mình LF.
Là các đầu mối hoặc dấu phân cách ở trên? Điều này có hiệu lực ở cuối tập tin và được biết là gây ra vấn đề.
Điều trị các tab và các ký tự điều khiển khác. Chúng tôi có thể giả định rằng một tab được sử dụng để căn chỉnh theo nhiều độ rộng 8 ký tự tiêu chuẩn từ đầu dòng, nhưng thực sự không có gì chắc chắn về điều này. Nhiều chương trình cho phép thay đổi vị trí tab.
Bộ ký tự & Mã hóa? Không có tiêu chuẩn chung để chỉ ra cái nào trong số này đã được sử dụng cho văn bản trong tệp. Việc gần nhất mà chúng ta có là tìm kiếm sự hiện diện của BOM cho biết mã hóa là một trong những mã được sử dụng cho Unicode. Từ giá trị BOM, chương trình đọc tệp có thể phân biệt giữa UTF-8 và UTF-16, v.v. và giữa các biến thể Little-Endian và Big-Endian của UTF-16, v.v. Không có tiêu chuẩn chung nào cho thấy rằng một tệp được mã hóa trong bất kỳ mã hóa phổ biến nào khác, chẳng hạn như CP-1252 hoặc KOI-8.
Và như thế. Không có siêu dữ liệu nào ở trên được ghi vào tệp văn bản - vì vậy người dùng cuối phải thông báo cho chương trình khi đọc tệp. Người dùng cuối phải biết các giá trị siêu dữ liệu cho bất kỳ tệp cụ thể nào hoặc có nguy cơ chương trình của họ sẽ sử dụng các giá trị siêu dữ liệu sai.
Bush che giấu sự thật
Hãy thử điều này trên Windows XP.
- Mở Notepad.
- Đặt phông chữ thành Arial Unicode MS. (Bạn có thể cần cài đặt nó trước; nếu bạn không thấy nó trong menu, nhấp vào "Hiển thị thêm phông chữ".)
- Nhập văn bản "Bush che giấu sự thật".
- Chọn
Save As
. Từ Encoding
menu, chọn ANSI
.
- Đóng Notepad.
- Mở lại tài liệu (ví dụ: bằng cách sử dụng
Start
, My Recent Documents
).
- Bạn sẽ thấy 畂 桳 栠 敨 獴 thay vì "Bush che giấu sự thật".
Điều này minh họa rằng IsTextUnicode
chức năng được sử dụng bởi Notepad đoán không chính xác rằng văn bản ANSI (thực sự là Trang 1252) là Unicode UTF-16LE không có BOM. Không có BOM trong một tệp được lưu dưới dạng ANSI
.
Windows 7
Với Windows 7, Microsoft đã điều chỉnh IsTextUnicode
để những điều trên không xảy ra. Trong sự vắng mặt của BOM, giờ đây có nhiều khả năng đoán ANSI (CP 1252) hơn Unicode (UTF-16LE). Do đó, với Windows-7, tôi hy vọng bạn có nhiều khả năng gặp phải vấn đề ngược lại: Một tệp chứa các ký tự Unicode có điểm mã lớn hơn 255, nhưng không có BOM, giờ đây có nhiều khả năng được đoán là ANSI - và do đó hiển thị không chính xác.
Ngăn chặn sự cố mã hóa
Hiện tại, cách tiếp cận tốt nhất dường như là sử dụng UTF-8 ở mọi nơi. Lý tưởng nhất là bạn sẽ mã hóa lại tất cả các tệp văn bản cũ thành UTF-8 và chỉ lưu các tệp văn bản dưới dạng UTF-8. Có các công cụ như recode và iconv có thể giúp với điều này.