อะไรคือความแตกต่างระหว่างไฟล์ Linux .txt และ Windows (การเข้ารหัส Unicode)


16

ฉันใช้ชุดอักขระ 128 ตัวที่กำหนดไว้ในมาตรฐาน ANSI ดั้งเดิมเท่านั้น

แต่โดยรวมแล้วไฟล์เหล่านั้นแตกต่างกันอย่างไร

ฉันไม่ได้กังวลกับการแสดงผลเช่นถ้าแท็บแสดงด้วยตัวอักษร 6 หรือ 8 ตัว แต่เป็นการแสดงภายในจริงในหน่วยความจำ

ความแตกต่างอย่างหนึ่งที่ฉันเคยได้ยินคือการใช้ \ r \ n (Windows) กับ \ n สำหรับการเลิกจ้างบรรทัด (Linux)


ฉันคิดว่าเครื่องหมายคำสั่งซื้อ byte กำลังฆ่า #! (บรรทัดแรก) ในไฟล์ php ที่ฉันถ่ายโอนจาก windows ไปยัง linux ไฟล์ทั้งหมดใช้งานได้ แต่ไม่สามารถหาล่ามได้ตามที่ควร ถ้าฉันพูดให้เข้ารหัสใน ANSI โดยการเลือกวิธีการเข้ารหัสในแผ่นจดบันทึกมันเป็น ASCII จริงหรือ Windows ทำอย่างอื่น

ดูว่าคุณมี bomstrip ในช่อง Gnu / Linux ของคุณหรือไม่ มันเป็นส่วนหนึ่งของ Debian (และอย่างน้อยก็บางคน) แต่อาจต้องติดตั้ง เป็นสิ่งจำเป็นเนื่องจาก Microsoft เพิ่ม BOM อย่างผิดพลาดไปยังจุดเริ่มต้นของไฟล์ utf-8
ctrl-alt-delor

คำตอบ:


17

"Unicode" บน Windows คือ UTF-16LE และอักขระแต่ละตัวคือ 2 หรือ 4 ไบต์ Linux ใช้ UTF-8 และอักขระแต่ละตัวอยู่ระหว่าง 1 ถึง 4 ไบต์

"ขั้นต่ำสุดยอดนักพัฒนาซอฟต์แวร์ทุกคนต้องรู้อย่างแน่นอนเกี่ยวกับ Unicode และชุดอักขระ (ไม่มีข้อแก้ตัว!)"


Windows เสียไบต์หรือไม่

1
หากคุณไม่ได้ใช้อะไรนอกละติน -1 ใช่
Ignacio Vazquez-Abrams

พวกเขาอยู่ในบทความที่ฉันเชื่อมโยงกับ
Ignacio Vazquez-Abrams

1
เรียกใช้การค้นหา UTF-16LE แต่ไม่พบในบทความ

1
ส่วนใหญ่ คุณต้องนับBOM ด้วยถ้ามี
Ignacio Vazquez-Abrams

11

ตัวแบ่งบรรทัด

Windows ใช้จุดสิ้นสุดของบรรทัดCRLF ( \r\n, 0D 0A) ในขณะที่ Unix เพิ่งใช้ LF ( \n, 0A)

การเข้ารหัสอักขระ

ทันสมัยที่สุด (เช่นตั้งแต่ปี 2004 หรือมากกว่านั้น) ระบบ Unix-like ทำให้UTF-8เป็นการเข้ารหัสตัวอักษรเริ่มต้น

อย่างไรก็ตาม Windows ขาดการสนับสนุนดั้งเดิมสำหรับ UTF-8 มันภายในทำงานใน UTF-16 และสันนิษฐานว่าcharสตริงชั่นอยู่ในมรดกหน้ารหัส โชคดีที่ Notepad สามารถอ่านไฟล์ UTF-8 ได้ ขออภัยการเข้ารหัส "ANSI" ยังคงเป็นค่าเริ่มต้น

อักขระพิเศษที่มีปัญหา

ทดแทน U + 001A

Windows (ไม่ค่อยมี) ใช้Ctrl+ Zเป็นอักขระสิ้นสุดไฟล์ ตัวอย่างเช่นหากคุณtypeไฟล์ที่พรอมต์คำสั่งมันจะถูกตัดทอนที่1Aไบต์แรก

บน Unix ไม่มีอะไรพิเศษCtrl+Z

U + FEFF ZERO ที่ไม่มีช่องว่าง (เครื่องหมายคำสั่งซื้อ Byte)

ใน Windows ไฟล์ UTF-8 มักจะเริ่มต้นด้วย "เครื่องหมายคำสั่งไบต์" EF BB BFเพื่อแยกความแตกต่างจากไฟล์ ANSI

บน Linux BOM ถูกทำให้หมดกำลังใจเพราะมันแบ่งสิ่งต่าง ๆ เช่นบรรทัด shebang ในเชลล์สคริปต์ นอกจากนี้จะไม่มีประโยชน์ที่จะมีลายเซ็น UTF-8 เมื่อ UTF-8 เป็นการเข้ารหัสเริ่มต้นอยู่แล้ว


1
Ctrl-Z ทำงานบน windows เช่นเดียวกับ Ctrl-D (หรือตัวละครอะไรก็ตามที่คุณผูกกับ EOF ด้วยstty) ทำงานบน Linux: ไดรเวอร์คอนโซลแปลมันให้จบไฟล์ อักขระสัญพจน์ไม่ปรากฏในสตรีมอินพุต มันแค่ทำให้ read () กลับ 0
psusi

ฉันคิดว่าเครื่องหมายคำสั่งซื้อ byte กำลังฆ่า #! (บรรทัดแรก) ในไฟล์ php ที่ฉันถ่ายโอนจาก windows ไปยัง linux ไฟล์ทั้งหมดใช้งานได้ แต่ไม่สามารถหาล่ามได้ตามที่ควร ถ้าฉันเข้ารหัสให้แน่นอนด้วยการเข้ารหัสใน ANSI โดยการเลือกวิธีการเข้ารหัสในแผ่นจดบันทึกมันเป็น ASCII จริงหรือ Windows ทำอย่างอื่นหรือไม่

1
เป็นมูลค่าการกล่าวขวัญว่า“ ANSI code page” แบบหลอกๆแม้ว่าจะยังปรากฏอยู่ในโปรแกรมเช่น Notepad นั้นเป็นชื่อเรียกที่ผิดและ Microsoft ยอมรับมานานแล้ว ดูen.wikipedia.org/wiki/Windows_code_pageสำหรับรายละเอียด
Incnis Mrsi

utf-8 ไม่มี BOM แต่ MS-Windows จะแทรกหนึ่งอัน ทำให้ไม่เป็นความจริง utf-8 หนึ่งในกฎของ utf-8 คือไฟล์ใด ๆ ที่สามารถแสดงใน ascii เป็นบิตสำหรับบิตเหมือนกันใน utf-8 นอกจากนี้คุณสามารถเริ่มอ่าน utf-8 ได้ทุกเมื่อในสตรีม
ctrl-alt-delor

3

สิ่งหนึ่งที่ฉันได้ยินคือการใช้ \ r \ n (Windows) กับ \ n สำหรับการขึ้นบรรทัดใหม่ (Linux)

ใช่. ตัวแก้ไขข้อความ UNIX ส่วนใหญ่จะจัดการสิ่งนี้โดยอัตโนมัติตัวแก้ไขโปรแกรมเมอร์ของ Windows อาจจัดการสิ่งนี้ตัวแก้ไขข้อความทั่วไป (ฐาน Notepad) จะไม่ทำงาน

Windows ดูเหมือนว่าจะต้องใช้ EOF (Ctrl-Z) เป็นจุดสิ้นสุดของไฟล์ในบริบทบางอย่างในขณะที่คุณอาจไม่เคยเห็นมันใน UNIX

โปรดจำไว้ว่า MacOS X เป็น UNIX ที่อยู่ด้านล่างดังนั้นจึงใช้จุดสิ้นสุดบรรทัด UNIX แม้ว่าก่อนหน้า OS X (MacOS 9 และต่ำกว่า) มันมีจุดสิ้นสุดของตัวเอง (\ r)

แก้ไข: ในรูปแบบอื่น ๆ CR และ LF:

  • \ n คือ ASCII 0x0A, ตัวดึงบรรทัด (LF)
  • \ r คือ ASCII 0x0D, Carriage return (CR)

\ r \ n และ \ n อยู่ในชุดอักขระ ASCII อยู่ที่ไหน en.wikipedia.org/wiki/File:ASCII_Code_Chart.svg

2
@Chris \ n คือ ASCII 0x0A, ตัวดึงข้อมูลบรรทัด \ r คือ ASCII 0x0D, Carriage return
Rich Homolka

@ Rich เกี่ยวกับ EOF คืออะไร? นี่คือตัวอักษร ANSI หรือไม่

2
@barlop เทอร์มินัลแปลการกดแป้น (ปกติจะเป็น ctrl-d ในระบบยูนิกซ์) เป็น EOF ยกเว้นว่าคีย์ควบคุมนี้ถูกปิดใช้งาน แอปพลิเคชันอ่าน EOF แทนรหัสจริงที่คุณกด กล่าวคือread()ส่งกลับค่าศูนย์ไบต์แทนอักขระเฉพาะใด ๆ
psusi

1
@barlop นั่นคือสิ่งที่ฉันพูด: มันจะไม่ส่งกลับตัวละครใด ๆ read () ส่งคืนจำนวนไบต์ที่เก็บไว้ในบัฟเฟอร์ของคุณ บน EOF เพียงแค่ให้คุณเป็นศูนย์ไบต์ นั่นคือสัญญาณที่คุณมาถึงจุดสิ้นสุดของไฟล์และไม่มีอะไรให้อ่านอีกต่อไป
psusi

1

การเข้ารหัส Unicode ใดที่ใช้ไม่ได้ขึ้นอยู่กับระบบปฏิบัติการ

แม้กระทั่ง notepad.exe ของ Windows ก็มีตัวเลือกในรายการ - (ฉันจะใส่เครื่องหมายวงเล็บในความหมายของ Notepad) ANSI (ไม่ใช่ Unicode), Unicode (notepad หมายถึง Unicode LE), Unicode Big Endian (BE), UTF-8

ANSI ไม่ใช่ยูนิโค้ดมันเกี่ยวข้องกับจำนวนอักขระที่ จำกัด มาก

แต่ดูว่า notepad สามารถทำ LE หรือ BE หรือ UTF-8 ได้

และแผ่นจดบันทึกด้านข้าง UTF-8 สามารถมีหรือไม่มี BOM ก็ได้

และฉันใช้ Windows กับ Cygwin แม้ว่าพอร์ต Windows อาจทำได้ดี \ r \ n แม้เมื่อคุณระบุ \ n เคยเห็นว่าทำเช่นนั้น

ไม่มีกฎใดข้อหนึ่งว่า Unicode เข้ารหัสระบบปฏิบัติการใดที่ใช้ มันจะไม่เป็นระบบปฏิบัติการที่ยืดหยุ่นมากหากมี

เมื่อต้องการดูความแตกต่างรู้ว่าซอฟต์แวร์การเข้ารหัสของซอฟต์แวร์ที่ใช้หรือข้อเสนออะไร

รับ Cygwin และ xxd และ / หรือโปรแกรมแก้ไขฐานสิบหกและดูสิ่งที่อยู่ภายในไฟล์จริงๆ ใช้คำสั่ง 'ไฟล์' เพื่อช่วยระบุไฟล์ จากนั้นคุณจะเห็นว่า UTF 16bit LE คืออะไร UTF 16 บิต BE คืออะไร UTF-8 คืออะไร (และ UTF-8 สามารถมีหรือไม่มี BOM)

บางครั้งคุณสามารถบอก notepad ให้บันทึกเป็น unicode (โดย notepad แปลว่า unicode 16 bit น้อย endian) และมันจะไม่ แต่เลือกฟอนต์ unicode เช่น arial unicode และคัดลอกตัวอักษรยูนิโค้ดจาก charmap และมันจะเป็นวิธีที่ดีในการดูว่า notepad หรือซอฟต์แวร์ใด ๆ กำลังทำอยู่โดยดูจากเลขฐานสิบหกของไฟล์

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.

คำสั่ง dd (คำสั่ง * nix ที่ฉันเรียกใช้จาก cygwin ภายใน windows) สามารถสลับได้

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>

และ Notepad เองสามารถบันทึกเป็น UTF-16 Big Endian หรือ UTF-16 Little Endian หรือ UTF-8

ป้อนคำอธิบายรูปภาพที่นี่

หากคุณเป็นคนที่มีความรู้ด้านเทคนิคหรือแม้กระทั่งผู้ใช้ notepad คุณจะไม่ถูกผูกมัดกับการเข้ารหัสเพราะระบบปฏิบัติการของคุณ!

ฉันคิดว่า UTF-8 เหมาะสมกว่า UTF-16, UTF-16 จะใช้ 16 บิตแม้สำหรับตัวอักษรที่ควรใช้เพียง 8 บิต อย่างไรก็ตามโปรดจำไว้ว่า charmap แสดงรหัส UTF-16

ประเสริฐ (โปรแกรมแก้ไขข้อความ windows) จะบันทึกยูนิโคดเป็น UTF-8 ตามค่าเริ่มต้น

ฉันใช้ Windows และ unicode บางครั้งและฉันใช้ UTF-8 เป็นส่วนใหญ่

และเนื่องจาก Windows มีความยืดหยุ่นทางเทคนิคอย่างน้อย linux จึงมีความยืดหยุ่นทางเทคนิคอย่างน้อย!


คุณเขียนคำสั่งfileและtypeภายใน Cygwin prompt หรือไม่
Vesnog

xxdและtypeคำสั่งจะหายไปในการติดตั้ง Cygwin มาตรฐานที่ฉันเข้าใจ นอกเหนือจากที่ฉันต้องการที่จะทำซ้ำผลลัพธ์ของคุณ
Vesnog

1
@Vesnog typeเป็นคำสั่งมาตรฐานที่มีอยู่แล้วใน cmd.exe xxdซึ่งส่วนใหญ่ไม่ได้ติดตั้งด้วย cygwin โดยค่าเริ่มต้น แต่เมื่อคุณติดตั้ง cygwin หรือหลังจากนั้นหากคุณเริ่มต้นการติดตั้ง cygwin คุณจะได้รับรายการคำสั่งยาว ๆ และเพียงพิมพ์ xxd ลงในช่องค้นหาการตั้งค่า cygwin และจะปรากฏขึ้น xxd สามารถใช้งานได้หลังจากการติดตั้ง vim7 เพื่อให้คุณได้รับจากที่นั่นด้วย
barlop

1
@Vesnog คุณสามารถเรียกใช้คำสั่ง cygwin ภายใน cygwin หรือนอก cygwin หากคุณเรียกใช้พวกเขานอก cygwin แล้วเพิ่ม c:\cygwin\bin(ถ้านั่นคือที่ไดเรกทอรีย่อย bin ของ cygwin) ในเส้นทางของคุณ นอกจากนี้ยังมีคำสั่ง cmd ภายในเช่น 'type' หรือ 'dir' หรือ exe ภายนอกเช่น calc.exe (เครื่องคำนวณ windows) สามารถเรียกใช้ / เปิดใช้จากภายใน cygwin ทุกอย่างที่สามารถวิ่งได้จาก cygwin สามารถวิ่งได้จาก cmd และในทางกลับกัน หากคุณต้องการใช้ทุบตีให้ใช้ cygwin และถ้าคุณพบปัญหากับคำพูดเดียวกับคำพูดคู่แล้วเรียกใช้คำสั่ง cygwin ภายใน cygwin และคำสั่ง cmd ภายใน cmd
barlop

1
@Vesnog xxd สามารถเขียนไฟล์ได้เช่นกันecho 61|xxd -r -p>a.aจากนั้นลองใช้type a.a ดังนั้นคุณจะได้รับการถ่ายโอนข้อมูลไบต์ด้วย xxd -p, จัดเรียงใหม่หรือแก้ไขไบต์แล้วป้อนลงใน xxd -r -p และรับไฟล์ใหม่ที่มีการเข้ารหัสที่แตกต่างกันหรือ ข้อมูลที่แตกต่างกันขึ้นอยู่กับข้อมูลเก่า คำสั่ง "file" กำลังหาการเข้ารหัสตามไบต์
barlop

-1

Linux ใช้ UTF-8 และอักขระแต่ละตัวอยู่ระหว่าง 1 ถึง 6 ไบต์ไม่ใช่ระหว่าง 1 และ 4 ไบต์

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

นี่ได้ระบุไว้แล้วในคำตอบที่ส่งในปี 2011
Ramhound
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.