it-swarm-vi.com

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

Vâng, 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 rất hay trên 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 đó trong \n tại sao Windows phải mất hai ký tự để làm điều này?

Tôi đang đọc cuốn sách của David Beazley Python 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.

108
sukhbir

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 nó 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. Đinh đã thông báo cho người đánh máy rằng cái kết đã gần kề, và để chuẩn bị cho nó.

133
user1249

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

\r là trả lại xe ngựa, đó 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, giúp 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ự.

21
Matt Ellen

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 bộ, ví dụ:.

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

Trong lịch sử, nguồn cấp dữ liệu có nghĩa là Platen - 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 trước đây là) 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!)

7
Frank Shearar

Lịch sử của nhân vật dòng mới (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 LF một mình làm 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ể quay lại từ bên phải sang đầ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. Trong thực tế, thường phải 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 di 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 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 theo Unix.

6
Craige

Có chuyện gì với mọi người hỏi "tại sao Unix có thể làm \n và khô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ả \n\r\n bình thường. Họ cũng xuất ra \r\n để mọi người vui vẻ. Một chương trình không chỉ đơn giản là "làm" hoặc \n hoặc là \r\n - nó chấp nhận một, cái kia hoặc cả hai và đầu ra một, khác, hoặc cả hai.
  3. Là một lập trình viên, điều này thực sự 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 giải quyết 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 làm \n thay vì chính xác\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 \n hoàn toàn biết rằng có một số giao thức và chương trình không thích nó?
5
Rei Miyasaka

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 nhiều kiểu 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ò.

4
Michael Kohne

Đây là một câu trả lời từ nguồn tốt nhất - Microsoft. Tại sao bộ kết thúc dòng 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 "vận chuyển trở lại" - ký tự điều khiển CR trả lại đầu in ("cỗ xe") cho cột 0 mà không tiến hành 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 cột số không (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?" mà là "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 đã sử dụng plain LF làm chuỗi 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 a LF có nên không đã đổi thành CR + LF. 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 được thông báo 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, do đó mức độ nhầm lẫn đã được nâng lên cao hơn nữa.

2
Ondra Žižka