Sự khác biệt giữa '\ n' và '\ r \ n'


99

Có, tôi biết rằng '\n'viết một dòng mới trong UNIX trong khi đối với Windows có hai chuỗi ký tự : '\r\n'. Tất cả điều này là rất tốt trong lý thuyết, nhưng câu hỏi của tôi là tại sao ? Tại sao nhân vật trở lại vận chuyển là thêm trong Windows? Nếu UNIX có thể làm điều đó tại \nsao phải mất hai ký tự Windows để làm điều này?

Tôi đang đọc cuốn sách Python của David Beazley và anh ấy nói:

Ví dụ: trên Windows, việc viết ký tự '\ n' thực sự xuất ra chuỗi hai ký tự '\ r \ n' (và khi đọc lại tệp, '\ r \ n' được dịch lại thành một '\ n' tính cách).

Tại sao phải nỗ lực thêm?

Tôi sẽ thành thực. Tôi đã biết sự khác biệt trong một thời gian dài nhưng chưa bao giờ bận tâm hỏi TẠI SAO. Tôi hy vọng điều đó được trả lời ngày hôm nay.

Cảm ơn vì đã dành thời gian cho tôi.


5
Cũng cần lưu ý rằng Windows không phải là người duy nhất sử dụng \r\n. Nó cũng được sử dụng bởi hầu hết các giao thức internet dựa trên văn bản (ví dụ: SMTP, HTTP, v.v.) với lý do chủ yếu giống như Windows (tức là lịch sử).
Dean Harding

3
Ngoài ra, khi ở Java và sử dụng các chuỗi định dạng (ví dụ System.out.printf()hoặc String.format()), hãy đảm bảo bạn sử dụng %nlàm CRLF cho các mục đích tương thích của hệ điều hành. \nbị phản đối
Gary Rowe

Tôi đã thấy \n\rnhiều lần. (Tôi nghĩ đó là thứ gì đó từ NetWare.)
grawity


1
Có rất ít chương trình Windows thực sự yêu cầu CRLF. CRLF có thể là mặc định, nhưng gần như mọi thứ sẽ tự động phát hiện và sử dụng LF tốt. Tôi có tất cả các trình soạn thảo văn bản của mình trên Windows được định cấu hình để sử dụng các tệp LF cho tất cả các tệp mới và thực sự không có vấn đề gì.
Kevin

Câu trả lời:


124

Tương thích ngược.

Windows tương thích ngược với MS-DOS (rất tích cực, thậm chí) và MS-DOS đã sử dụng quy ước CR-LF vì MS-DOS tương thích với CP / M-80 (hơi tình cờ) sử dụng quy ước CR-LF vì điều đó là cách bạn lái máy in (vì máy in ban đầu là máy chữ do máy tính điều khiển).

Máy in có một lệnh riêng để di chuyển giấy lên một dòng sang một dòng mới và một lệnh riêng để trả lại cỗ xe (nơi gắn giấy) trở lại lề trái.

Đó là lý do tại sao. Và, vâng, điều đó thật khó chịu, nhưng đó là một phần của thỏa thuận trọn gói cho phép MS-DOS giành được CP / M và Windows 95 để giành chiến thắng trước tất cả các GUI khác trên DOS và Windows XP để tiếp quản từ Windows 98.

(Lưu ý: Máy in laser hiện đại vẫn có các lệnh này vì chúng cũng tương thích ngược với máy in trước đó - đặc biệt HP làm tốt điều này)

Đối với những người không quen thuộc với máy đánh chữ, đây là video cho thấy cách gõ được thực hiện: http://www.youtube.com/watch?v=LJvGiU_UyEQ . Lưu ý rằng giấy đầu tiên được di chuyển lên, và sau đó vận chuyển được trả lại, ngay cả khi nó xảy ra trong một chuyển động đơn giản. Các ding thông báo cho người đánh máy rằng kết thúc đã gần, và để chuẩn bị cho nó.


3
Làm thế nào mà Unix với \ n của nó chỉ được sử dụng để làm việc với những máy in ngày xưa đó? Tôi giả sử họ đã có hệ điều hành Unix kết nối với máy in kiểu máy chữ?
Senthil Kumaran

3
@Senthil, trong Unix ký tự dòng mới được chuyển đổi bởi trình điều khiển cuối. Nó chỉ là một quyết định thiết kế khác nhau.

2
@Senthil, chính xác là, trong các máy in và thiết bị đầu cuối Unix được trừu tượng hóa trong hệ điều hành và mô tả của chúng xác định chuỗi byte nào được tạo cho thiết bị. CP / M không có sự trừu tượng hóa như vậy để lại tất cả cho chương trình đang chạy - điều này rất có thể bởi vì tất cả các chương trình không cần thiết nên việc có nó trong hệ điều hành thường trú sẽ lấy đi bộ nhớ quý giá từ các chương trình không cần nó. Hãy nhớ rằng CP / M được thiết kế cho hệ thống 16 Kilobyte .

1
"Vì vậy, một tính năng thiết kế chính của hệ thống giao thông tiên tiến nhất thế giới được xác định ban đầu được xác định bởi chiều rộng của mông ngựa." Và đó là với phần mềm là tốt. astrodigital.org/space/stshorse.html
Ryan Michela

1
@Ryan, truyền thuyết đô thị.

20

Theo như tôi biết thì đây là thời của những người đánh máy.

\r là vận chuyển trở lại, đó là những gì di chuyển nơi bạn đang gõ trên trang trở lại bên trái (hoặc bên phải nếu đó là văn hóa của bạn)

\n là dòng mới, di chuyển giấy của bạn lên một dòng.

Chỉ thực hiện một trong những điều này trên một máy đánh chữ sẽ đặt bạn vào vị trí sai để bắt đầu viết một dòng văn bản mới.

Khi máy tính xuất hiện, tôi đoán một số người vẫn giữ mô hình cũ, nhưng những người khác nhận ra rằng điều đó là không cần thiết và gói gọn một dòng mới đầy đủ dưới dạng một ký tự.


7
Vậy tại sao Windows vẫn dính vào nó?
sukhbir

8
Tương thích ngược. Hãy tưởng tượng có bao nhiêu tài liệu văn bản sẽ bị hỏng nếu chúng thay đổi ngay bây giờ
Matt Ellen

4
Nói một cách chính xác, "lẻ bóng" ở đây là unixoid 'chỉ sử dụng dòng mới', được thực hiện ban đầu (tôi tin) để giảm số lượng ký tự được lưu trữ (bản dịch sang CR LF được thực hiện trong trình điều khiển đầu cuối, đó là cờ 'onlcr' điều khiển nó cho đầu ra.
Vatine

3
Windows có một Người tiền nhiệm tên là DOS, có cùng dòng kết thúc. Windows giữ khả năng tương thích. DOS đã có tiền thân, cụ thể là CP / M. Điều đó cũng được sử dụng CRLF. DOS giữ khả năng tương thích. Sự phát triển của CP / M bị ảnh hưởng bởi các TOPS. Và bạn có thể đoán, họ đã sử dụng dòng nào. :-) Tính tương thích giải thích nhiều.
Mnementh

5
OK, nhưng tại sao Notepad vẫn không nhận ra kết thúc dòng "\ n"?
dan04

8

Tôi không biết đây có phải là kiến ​​thức phổ biến không, nhưng cần lưu ý rằng CR vẫn được hiểu bởi các trình giả lập thiết bị đầu cuối hiện đại:

$ printf "hey world\rsup\n"
sup world

Nó tiện dụng cho các chỉ số tiến độ, ví dụ

for i in {1..100}
do
    printf "\rLoading... %d%%" $i
    sleep 0.01
done
echo

1
Trên các máy in dòng cũ của IBM (ví dụ: 1403), quy ước là coi ký tự đầu tiên của bộ đệm dòng là ký tự điều khiển vận chuyển. Trống có nghĩa là để tiến một dòng và in. Plus có nghĩa là bỏ qua khoảng cách và được sử dụng, ví dụ, để gạch chân. Số không có nghĩa là không gian gấp đôi và trừ cho không gian ba. Khoảng cách '1' được đặt ở đầu trang tiếp theo và các chữ số khác được nâng lên vị trí dọc do người dùng xác định (được sử dụng để điền vào các biểu mẫu được in sẵn).
George

7

Trong lịch sử, nguồn cấp dữ liệu có nghĩa là trục lăn - con lăn mà bạn nhập - xoay một dòng, khiến văn bản xuất hiện trên dòng tiếp theo ... nhưng trong cột tiếp theo.

Trả về vận chuyển có nghĩa là "trả lại bit mà bạn nhập vào đầu dòng".

Windows sử dụng CR + LF vì MS-DOS đã làm, vì CP / M đã làm, bởi vì nó có ý nghĩa đối với các dòng nối tiếp.

Unix đã sao chép quy ước \ n của nó vì Multics đã làm.

Tôi nghi ngờ nếu bạn đào đủ xa, bạn sẽ thấy bất đồng chính trị giữa những người thực hiện!

(Bạn đã bỏ qua một chút thú vị, trong đó quy ước Mac (hoặc đã từng) chỉ sử dụng CR để phân tách các dòng. Và bây giờ Unicode cũng có dấu tách dòng riêng, U + 2028!)


Ồ không biết gì về máy Mac ...
Michael K

Tôi không chắc chắn bạn sẽ tìm thấy một sự bất đồng chính trị. Cũng có thể bạn sẽ thấy mọi người làm những việc tương tự một cách độc lập.
David Thornley

1
Khi có các cơ quan tiêu chuẩn khác nhau tham gia? Tôi sẽ ngạc nhiên khi không tìm thấy lý do chính trị!
Frank Shearar

6

Lịch sử của nhân vật Newline (Wikipedia):

ASCII được phát triển đồng thời bởi ISO và ASA, tổ chức tiền thân của ANSI. Trong giai đoạn 1963, 191968, các tiêu chuẩn dự thảo ISO đã hỗ trợ việc sử dụng CR + LF hoặc một mình như một dòng mới, trong khi các bản nháp ASA chỉ hỗ trợ CR + LF.

Trình tự CR + LF được sử dụng phổ biến trên nhiều hệ thống máy tính đời đầu đã sử dụng máy teletype, điển hình là ASR33, như một thiết bị điều khiển, bởi vì trình tự này được yêu cầu để định vị các máy in đó khi bắt đầu một dòng mới. Trên các hệ thống này, văn bản thường được soạn thảo thường xuyên để tương thích với các máy in này, vì khái niệm trình điều khiển thiết bị ẩn các chi tiết phần cứng như vậy từ ứng dụng chưa được phát triển tốt; các ứng dụng phải nói chuyện trực tiếp với máy teletype và tuân theo các quy ước của nó.

Sự tách biệt của hai chức năng che giấu thực tế là đầu in không thể trở về từ đầu bên phải đến đầu dòng tiếp theo trong thời gian một ký tự. Đó là lý do tại sao chuỗi luôn được gửi với CR đầu tiên. Trên thực tế, thường cần gửi thêm các ký tự (CR hoặc NUL không liên quan, bị bỏ qua) để cho thời gian đầu in chuyển sang lề trái.

Ngay cả sau khi teletype được thay thế bởi các thiết bị đầu cuối máy tính có tốc độ truyền cao hơn, nhiều hệ điều hành vẫn hỗ trợ gửi tự động các ký tự điền này, để tương thích với các thiết bị đầu cuối rẻ hơn yêu cầu nhiều lần ký tự để cuộn màn hình.

MS-DOS (1981) đã thông qua CR / LF của CP / M; Việc sử dụng CR + LF của CP / M có ý nghĩa đối với việc sử dụng các thiết bị đầu cuối máy tính thông qua các đường nối tiếp. Quy ước này được kế thừa bởi hệ điều hành Windows sau này của Microsoft.

Hệ điều hành Multics bắt đầu phát triển vào năm 1964 và sử dụng một mình LF làm dòng mới. Unix tuân theo thực tiễn Multics và các hệ thống sau này cũng chạy theo Unix.


Trên thiết bị đầu cuối bàn phím máy in IBM 2741 cũ, thành phần máy in là một máy đánh chữ kiểu nảy nảy chọn lọc của IBM. Thay đổi thành chữ hoa khiến bóng xoay, mất thêm thời gian. Trong mã ký tự EBCDIC, các ký tự chữ hoa có vị trí 1 bit ở vị trí 6. Vì vậy, khoảng trống EBCDIC (0x40) là chữ hoa! Nếu bạn đang in một tài liệu dài (ví dụ: một luận án), bạn có thể tăng tốc độ đầu ra bằng cách dịch khoảng trắng giữa các từ viết thường thành NUL hoặc viết trống (họ đã sử dụng một ký tự khác, IL nếu bộ nhớ phục vụ, để giới thiệu độ trễ cần thiết, ví dụ , khi trở về hoặc lập bảng).
George

5

Có gì với những người hỏi "tại sao Unix có thể làm mà \nkhông phải Windows"? Đó là một câu hỏi kỳ lạ.

  1. Hệ điều hành gần như không có gì để làm với nó. Đó là vấn đề về cách các ứng dụng, thư viện, giao thức và định dạng tệp xử lý mọi thứ. Khác với việc HĐH đọc / ghi cấu hình dựa trên văn bản hoặc các lệnh dòng lệnh, sẽ không có ý nghĩa gì đối với hệ điều hành.
  2. Hầu hết các ứng dụng Windows có thể đọc cả hai \n\r\ntốt. Họ cũng đầu ra \r\nđể mọi người đều hạnh phúc. Một chương trình không chỉ đơn giản là "làm" \nhoặc \r\n- nó chấp nhận cái này, cái kia, hoặc cả hai, và đưa ra cái này, cái kia hoặc cả hai.
  3. Là một lập trình viên, điều này thực sự gần như không bao giờ làm phiền bạn. Thực tế, mọi ngôn ngữ / nền tảng đều có các phương tiện để viết dòng cuối chính xác và đọc mạnh mẽ nhất. Lần duy nhất tôi phải xử lý vấn đề là khi tôi viết một máy chủ HTTP - và đó là do một trình duyệt nhất định (gợi ý: trình duyệt phổ biến nhất tiếp theo sau IE) đang hoạt động \nthay vì đúng \r\n .
  4. Một câu hỏi thích hợp hơn nhiều là, tại sao nhiều ứng dụng Unix hiện đại chỉ xuất ra \nhoàn toàn biết rằng có một số giao thức và chương trình không thích nó?

3
Một câu hỏi thích hợp khác: vì nhiều giao thức được phát triển chủ yếu trên các hệ thống Unix, tại sao chúng không sử dụng '\ n'?
David Thornley

@DavidThornley Vì \ r \ n có nhiều khả năng hoạt động đa nền tảng (\ r cho các máy Mac cũ hơn, \ r \ n cho các cửa sổ và \ n cho * nix).
Cơ bản

4

Lý do các quy ước giữ trên các hệ thống khác nhau của họ (\ n trên các hệ thống loại unix, \ r \ n trên Windows, v.v.) là vì một khi bạn đã chọn một quy ước, bạn KHÔNG THỂ thay đổi nó mà không phá vỡ một loạt các tệp của mọi người. Và đó thường là nhíu mày.

Các hệ thống kiểu Unix đã được phát triển (rất sớm) sử dụng các mô hình teletype khác nhau và đến một lúc nào đó, ai đó đã quyết định thiết bị sẽ vận chuyển trở lại khi nó thực hiện một nguồn cấp dữ liệu.

Windows đến từ DOS, vì vậy đối với Windows, câu hỏi thực sự là: Tại sao DOS sử dụng chuỗi cr / lf này? Tôi đoán nó có liên quan đến CP / M, trong đó DOS có một số gốc rễ. Một lần nữa, các mô hình cụ thể của teletype có thể đã đóng một vai trò.


Hmm thú vị.
sukhbir

1
Tại sao Windows không thể xử lý các dòng kết thúc bằng \n, nhưng tiếp tục sử dụng \r\ncho đến bây giờ? Nếu họ đã làm điều đó bắt đầu với Windows XP, giờ đây họ có thể bắt đầu lưu tệp \nthay vì \r\n.
DisgruntledGoat

1
Windows không có gì để làm với nó. Đó là quyết định của ứng dụng và hầu hết các ứng dụng sẽ đọc cả '\ n' và '\ r \ n' và viết '\ r \ n' - vì vậy mọi người đều vui vẻ.
Rei Miyasaka

2

Đây là một câu trả lời từ nguồn tốt nhất - Microsoft. Tại sao là dòng kết thúc CR + LF?

Giao thức này bắt nguồn từ thời của teletypewriters. CR là viết tắt của "cỗ xe trở về" - ký tự điều khiển CR trả đầu in ("cỗ xe") về cột 0 mà không tiến lên giấy. LF là viết tắt của "linefeed" - ký tự điều khiển LF nâng cao một dòng giấy mà không di chuyển đầu in. Vì vậy, nếu bạn muốn trả lại đầu in về cột 0 (sẵn sàng in dòng tiếp theo) và tiến lên giấy (để nó in trên giấy mới), bạn cần cả CR và LF.

Nếu bạn truy cập các tài liệu giao thức internet khác nhau, chẳng hạn như RFC 0821 (SMTP), RFC 1939 (POP), RFC 2060 (IMAP) hoặc RFC 2616 (HTTP), bạn sẽ thấy rằng tất cả đều chỉ định CR + LF là trình tự kết thúc dòng. Vì vậy, câu hỏi thực sự không phải là "Tại sao CP / M, MS-DOS và Win32 sử dụng CR + LF làm đầu cuối dòng?" nhưng thay vì "Tại sao người khác chọn khác với các tài liệu tiêu chuẩn này và sử dụng một số đầu cuối dòng khác?"

Unix đã thông qua LF đơn giản như là trình tự kết thúc dòng. Nếu bạn nhìn vào các tùy chọn stty, bạn sẽ thấy tùy chọn onlcr chỉ định xem có nên đổi một thay đổi thành CR + LF hay không. Nếu bạn cài đặt sai, bạn sẽ nhận được văn bản bậc thang, trong đó

each
    line
        begins

nơi dòng trước rời đi. Vì vậy, ngay cả unix, khi để ở chế độ thô, yêu cầu CR + LF chấm dứt các dòng. CR ẩn trước LF là một phát minh unix, có thể là một nền kinh tế, vì nó tiết kiệm một byte trên mỗi dòng.

Tổ tiên unix của ngôn ngữ C đã đưa quy ước này vào tiêu chuẩn ngôn ngữ C, chỉ yêu cầu "\ n" (mã hóa LF) để chấm dứt các dòng, đặt gánh nặng lên các thư viện thời gian chạy để chuyển đổi dữ liệu tệp thô thành các dòng logic.

Ngôn ngữ C cũng giới thiệu thuật ngữ "dòng mới" để diễn tả khái niệm "bộ kết thúc dòng chung". Tôi đã nói rằng ủy ban ASCII đã thay đổi tên của ký tự 0x0A thành "dòng mới" vào khoảng năm 1996, vì vậy mức độ nhầm lẫn đã được nâng lên cao hơn nữa.

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.