Sự khác biệt giữa các tệp .txt của Linux và Windows (mã hóa Unicode)


16

Tôi chỉ sử dụng bộ ký tự 128 được xác định trong tiêu chuẩn ANSI gốc.

Nhưng nói chung, các tập tin được cài đặt khác nhau như thế nào.

Tôi không quan tâm đến màn hình, tức là nếu một tab được hiển thị với 6 hoặc 8 ký tự nhưng biểu diễn bên trong thực tế trong bộ nhớ

Một điểm khác biệt tôi từng nghe là việc sử dụng \ r \ n (Windows) so với \ n để chấm dứt dòng (Linux).


Tôi nghĩ rằng dấu thứ tự byte đang giết chết #! (Dòng đầu tiên) trong các tệp php của tôi, tôi đã chuyển từ windows sang linux. Toàn bộ tệp hoạt động nhưng nó không thể tìm thấy trình thông dịch như bình thường. Nếu tôi chắc chắn đảm bảo mã hóa trong ANSI bằng cách chọn phương thức mã hóa trong notepad thì đó là ASCII thật hay Windows có làm gì khác không

Xem bạn có bomstrip trên hộp Gnu / Linux của bạn không. Nó là một phần của Debian (và ít nhất là một số khác), nhưng có thể cần cài đặt. Điều này là cần thiết bởi vì Microsoft đã thêm nhầm BOM vào đầu tập tin utf-8.
ctrl-alt-delor 18/03/18

Câu trả lời:


17

"Unicode" trên Windows là UTF-16LE và mỗi ký tự là 2 hoặc 4 byte. Linux sử dụng UTF-8 và mỗi ký tự nằm trong khoảng từ 1 đến 4 byte.

"Tối thiểu tuyệt đối mỗi nhà phát triển phần mềm tuyệt đối, phải tích cực phải biết về bộ ký tự Unicode và ký tự (Không có lý do!)"


Windows lãng phí một byte?

1
Nếu bạn không sử dụng bất cứ thứ gì ngoài tiếng Latin-1, vâng.
Ignacio Vazquez-Abrams

Chúng nằm trong bài báo tôi liên kết đến.
Ignacio Vazquez-Abrams

1
Chạy tìm kiếm UTF-16LE nhưng không tìm thấy nó trong bài viết.

1
Hầu hết. Bạn cũng cần phải đếm BOM nếu có.
Ignacio Vazquez-Abrams

11

Ngắt dòng

Windows sử dụng các kết thúc dòng CRLF ( \r\n, 0D 0A) trong khi Unix chỉ sử dụng LF ( \n, 0A).

Mã hóa ký tự

Hầu hết các hệ thống hiện đại (ví dụ, từ năm 2004 trở đi) đều biến UTF-8 thành mã hóa ký tự mặc định.

Tuy nhiên, Windows thiếu hỗ trợ riêng cho UTF-8. Nó hoạt động nội bộ trong UTF-16 và giả sử rằng các charchuỗi dựa trên nằm trong một trang mã kế thừa . May mắn thay, Notepad có khả năng đọc các tệp UTF-8; thật không may, mã hóa "ANSI" vẫn là mặc định.

Nhân vật đặc biệt có vấn đề

ĐĂNG KÝ U + 001A

Windows (hiếm khi) sử dụng Ctrl+ Zlàm ký tự cuối tập tin. Ví dụ, nếu bạn typemột tệp tại dấu nhắc lệnh, nó sẽ bị cắt ở 1Abyte đầu tiên .

Trên Unix, Ctrl+ Zkhông có gì đặc biệt.

Z + FEFF ZERO VỚI KHÔNG GIAN KHÔNG CÓ BREAK (Dấu hiệu đơn hàng)

Trên Windows, các tệp UTF-8 thường bắt đầu bằng "dấu thứ tự byte" EF BB BFđể phân biệt chúng với các tệp ANSI.

Trên Linux, BOM không được khuyến khích vì nó phá vỡ những thứ như dòng shebang trong các tập lệnh shell. Thêm vào đó, thật vô nghĩa khi có chữ ký UTF-8 khi UTF-8 là mã hóa mặc định.


1
Ctrl-Z hoạt động trên các cửa sổ giống như Ctrl-D (hoặc bất kỳ ký tự nào bạn đã liên kết với EOF stty) trên Linux: trình điều khiển bảng điều khiển dịch nó đến cuối tệp. Ký tự chữ không xuất hiện trong luồng đầu vào; nó chỉ khiến read () trở về 0.
psusi

Tôi nghĩ rằng dấu thứ tự byte đang giết chết #! (Dòng đầu tiên) trong các tệp php của tôi, tôi đã chuyển từ windows sang linux. Toàn bộ tệp hoạt động nhưng nó không thể tìm thấy trình thông dịch như bình thường. Nếu tôi chắc chắn đảm bảo mã hóa trong ANSI bằng cách chọn phương thức mã hóa trong notepad thì đó có phải là ASCII thật hay Windows có làm gì khác không?

1
Điều đáng nói là trang mã ANSI giả thuật ngữ, mặc dù vẫn xuất hiện trong các chương trình như Notepad, nhưng hoàn toàn là một cách hiểu sai và Microsoft đã thừa nhận điều này từ lâu. Xem en.wikipedia.org/wiki/Windows_code_page để biết chi tiết.
Incni Mrsi 18/08/2015

utf-8 không có BOM, nhưng MS-Windows chèn một. Làm cho nó không đúng utf-8. Một trong những quy tắc của utf-8 là bất kỳ tệp nào có thể được biểu thị bằng ascii, đều giống hệt bit trong utf-8. Ngoài ra, bạn có thể bắt đầu đọc utf-8 tại bất kỳ điểm nào trong luồng.
ctrl-alt-delor

3

Một điểm khác biệt tôi từng nghe là việc sử dụng \ r \ n (Windows) so với \ n để ngắt dòng (Linux).

Đúng. Hầu hết các trình soạn thảo văn bản UNIX sẽ tự động xử lý việc này, các biên tập viên lập trình Windows có thể xử lý việc này, các trình soạn thảo văn bản chung (Notepad cơ bản) sẽ không.

Windows dường như cũng cần EOF (Ctrl-Z) là END OF FILE trong một số ngữ cảnh, trong khi bạn có thể sẽ không bao giờ thấy nó trên UNIX.

Hãy nhớ rằng MacOS X bây giờ là UNIX bên dưới, vì vậy nó sử dụng các kết thúc dòng UNIX. Mặc dù trước OS X (MacOS 9 trở xuống), nó đã có kết thúc riêng (\ r)

EDIT: ở định dạng khác CR và LF:

  • \ n là ASCII 0x0A, Nguồn cấp dữ liệu (LF)
  • \ r là ASCII 0x0D, Vận chuyển trở lại (CR)

\ R \ n và \ n ở đâu trong bộ ký tự ASCII? vi.wikipedia.org/wiki/File:ASCII_Code_Chart.svg

2
@Chris \ n là ASCII 0x0A, Nguồn cấp dữ liệu. \ r là ASCII 0x0D, Vận chuyển trở lại
Rich Homolka

@Rich Còn EOF thì sao? Đây có phải là một nhân vật ANSI?

2
@barlop, thiết bị đầu cuối dịch tổ hợp phím (thường là ctrl-d trên các hệ thống unix) thành EOF, trừ khi khóa điều khiển này đã bị tắt. Ứng dụng đọc EOF chứ không phải là khóa thực tế bạn nhấn. Điều đó có nghĩa là, read()trả về 0 byte thay vì bất kỳ ký tự cụ thể nào.
psusi

1
@barlop, đó là những gì tôi đã nói: nó không trả lại bất kỳ ký tự nào . read () trả về số byte mà nó được lưu trữ trong bộ đệm của bạn. Trên EOF, nó chỉ đơn giản cung cấp cho bạn byte không. Đó là tín hiệu cho thấy bạn đã đến cuối tập tin và không còn gì để đọc nữa.
psusi

1

Những gì mã hóa Unicode được sử dụng không dựa trên hệ điều hành.

Ngay cả Windows notepad.exe cũng có các tùy chọn được liệt kê- (tôi sẽ đặt trong ngoặc đơn nghĩa là notepad nghĩa là gì) ANSI (không phải unicode), Unicode (notepad có nghĩa là Unicode LE), Unicode Big Endian (BE), UTF-8

ANSI không unicode nó liên quan đến số lượng ký tự rất hạn chế, vì vậy hãy đặt nó sang một bên.

Nhưng xem ngay cả notepad cũng có thể làm LE, hoặc BE hoặc UTF-8

Và bỏ qua một bên, UTF-8 có thể có hoặc không có BOM.

Và tôi sử dụng Windows với Cygwin mặc dù các cổng Windows có thể làm tốt \ r \ n ngay cả khi bạn chỉ định \ n Đã thấy sed làm điều đó.

Không có một quy tắc nào về việc mã hóa Unicode mà một hệ điều hành cụ thể sử dụng. Nó sẽ không phải là một hệ điều hành rất linh hoạt nếu có.

Để thực sự thấy sự khác biệt, hãy biết Phần mềm, những gì Mã hóa một phần mềm sử dụng hoặc cung cấp.

Nhận Cygwin và xxd, và / hoặc trình soạn thảo hex và xem xét những gì thực sự bên trong tệp. Sử dụng lệnh 'tập tin' để giúp xác định một tập tin. Sau đó, bạn thực sự thấy UTF 16bit LE là gì. UTF 16bit BE là gì. UTF-8 là gì (và UTF-8 có thể có hoặc không có BOM).

Đôi khi bạn có thể yêu cầu notepad lưu dưới dạng unicode (theo đó notepad có nghĩa là unicode 16 bit endian), và nó sẽ không. Nhưng chọn một phông chữ unicode như arial unicode, và sao chép một số ký tự unicode từ charmap và nó sẽ .. Và một cách tốt để xem notepad hoặc bất kỳ phần mềm nào đang làm, là bằng cách xem hex của tệp

C:\asdf>notepad.exe a.a

C:\asdf>file a.a
a.a; Little-endian UTF-16 Unicode text, with no line terminators

C:\asdf>type a.a
aaa慡ൡ <-- though displayed aaa followed by some boxes in my cmd window
C:\asdf>

C:\asdf>xxd a.a
0000000: fffe 6100 6100 6100 6161 610d            ..a.a.a.aaa.

C:\asdf>

^^ The portion of the byte that stores the 61 is the lower value portion which with LE is stored first.

Lệnh dd (lệnh * nix tôi chạy từ cygwin trong windows) có thể chuyển đổi nó

C:\asdf>xxd -p a.a
fffe6100610061006161610d

C:\asdf>file a.a
a.a; Little-endian UTF-16 Unicode text, with no line terminators

C:\asdf>dd if=a.a conv=swab of=a.a2
0+1 records in
0+1 records out
12 bytes (12 B) copied, 0 seconds, Infinity B/s

C:\asdf>type a.a2
a  a a aaa
C:\asdf>xxd -p a.a2
feff00610061006161610d61

C:\asdf>file a.a2
a.a2; Big-endian UTF-16 Unicode text, with no line terminators

C:\asdf>

Và bản thân notepad có thể lưu dưới dạng UTF-16 Big Endian hoặc UTF-16 Little Endian hoặc UTF-8

nhập mô tả hình ảnh ở đây

Nếu bạn là người kỹ thuật hoặc thậm chí chỉ là người dùng notepad, bạn không bị ràng buộc với một mã hóa vì hệ điều hành của bạn!

Tôi cho rằng UTF-8 có ý nghĩa hơn UTF-16, UTF-16 sẽ sử dụng 16 bit ngay cả đối với các ký tự chỉ cần 8 bit. Ngoài ra, hãy nhớ rằng charmap hiển thị mã UTF-16.

Sublime (Trình soạn thảo văn bản windows) lưu unicode dưới dạng UTF-8 theo mặc định.

Tôi sử dụng Windows và đôi khi là unicode và tôi đang sử dụng UTF-8.

Và vì Windows linh hoạt về mặt kỹ thuật, linux ít nhất cũng linh hoạt về mặt kỹ thuật!


Bạn đã viết các lệnh filetypebên trong dấu nhắc Cygwin?
Vesnog

xxdtypecác lệnh bị thiếu trong cài đặt Cygwin tiêu chuẩn tôi đoán. Ngoài ra tôi muốn tái tạo kết quả của bạn.
Vesnog

1
@Vesnog typelà một lệnh tiêu chuẩn được tích hợp trong cmd.exe xxdrất có thể không được cài đặt với cygwin theo mặc định, nhưng khi bạn cài đặt cygwin hoặc sau nó, nếu bạn bắt đầu thiết lập cygwin, bạn sẽ nhận được một danh sách dài các lệnh bạn có thể cài đặt để sử dụng trong cygwin, và chỉ cần gõ xxd vào hộp tìm kiếm thiết lập cygwin và nó xuất hiện. xxd cũng có sẵn từ sau khi cài đặt vim7 để bạn cũng có thể lấy nó từ đó.
barlop

1
@Vesnog bạn có thể chạy các lệnh cygwin bên trong cygwin hoặc bên ngoài cygwin. Nếu bạn chạy chúng bên ngoài cygwin thì hãy thêm c:\cygwin\bin(nếu đó là thư mục con bin của Cygwin), vào đường dẫn của bạn. Ngoài ra, bất kỳ lệnh cmd nội bộ nào như 'type' hoặc 'dir' hoặc bất kỳ exe bên ngoài nào như calc.exe (máy tính windows) đều có thể được chạy / khởi chạy từ bên trong cygwin. Khá nhiều thứ có thể chạy từ cygwin có thể chạy từ cmd và ngược lại. Nếu bạn muốn sử dụng bash thì hãy sử dụng cygwin và nếu bạn gặp vấn đề với dấu ngoặc kép so với dấu ngoặc kép thì hãy chạy các lệnh cygwin trong cygwin và cmd trong cmd.
barlop

1
@Vesnog xxd cũng có thể viết một tệp, ví dụ như vậy, echo 61|xxd -r -p>a.ahãy thử type a.aVì vậy, bạn thực sự có thể nhận được một byte kết xuất với xxd -p, sắp xếp lại hoặc sửa đổi các byte sau đó đưa nó vào xxd -r -p và nhận một tệp khác với mã hóa khác hoặc dữ liệu khác nhau dựa trên dữ liệu cũ. Lệnh "file" đang tìm ra mã hóa, dựa trên các byte.
barlop

-1

Linux sử dụng UTF-8 và mỗi ký tự nằm trong khoảng từ 1 đến 6 byte, không phải từ 1 đến 4 byte.

U00000000 - U0000007F: 0xxxxxxx
U00000080 - U000007FF: 110xxxxx 10xxxxxx
U00000800 - U0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U00010000 - U001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U00200000 - U03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U04000000 - U7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

Điều này đã được nêu trong một câu trả lời được gửi vào năm 2011
Ramhound
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.