Điều này là dành cho các lý do lịch sử (hoặc như tôi muốn nói, kích động). Các chế độ mở tệp được kế thừa từ thư viện stdio C và do đó chúng tôi theo dõi nó.
Đối với Windows, không có sự khác biệt giữa tệp văn bản và tệp nhị phân, giống như trong bất kỳ bản sao Unix nào. Không, ý tôi là! - Có (đã) hệ thống tập tin/hệ điều hành, trong đó tập tin văn bản là con thú hoàn toàn khác nhau từ tập tin đối tượng và như vậy. Trong một số bạn đã phải xác định độ dài tối đa của các dòng trước và các bản ghi kích thước cố định đã được sử dụng ... hóa thạch từ thời điểm các thẻ đục lỗ 80 cột và như vậy. May mắn thay, không phải như vậy trong Unices, Windows và Mac.
Tuy nhiên - tất cả những thứ khác bằng nhau - Unix, Windows và Mac hystorically khác nhau về những ký tự họ sử dụng trong luồng đầu ra để đánh dấu kết thúc của một dòng (hoặc cùng một thứ, như dấu phân cách giữa các dòng). Trong Unix, \ x0A (\ n) được sử dụng. Trong Windows, trình tự của hai ký tự \ x0D \ x0A (\ r \ n) được sử dụng; trên máy Mac - chỉ \ xOD (\ r). Dưới đây là một số manh mối về nguồn gốc của việc sử dụng hai ký hiệu đó - mã ASCII 10 được gọi là Nguồn cấp dữ liệu (LF) và khi được gửi tới teletype, sẽ làm cho nó di chuyển xuống một dòng (Y ++), mà không thay đổi chiều ngang của nó (X) Chức vụ. Mặt sau vận chuyển (CR) - Mặt khác ASCII 13 sẽ làm cho việc vận chuyển in trở về đầu dòng (X = 0) mà không cần cuộn xuống một dòng. Vì vậy, khi gửi đầu ra cho máy in, cả hai \ r và \ n phải được gửi đi, do đó, việc vận chuyển sẽ di chuyển đến đầu của một dòng mới. Bây giờ khi gõ trên bàn phím thiết bị đầu cuối, các nhà khai thác tự nhiên được dự kiến sẽ nhấn một phím và không phải hai cho cuối dòng. Điều đó trên Apple] [là chìa khóa 'Return' (\ r).
Dù sao thì đây là cách mọi thứ được giải quyết.Những người sáng tạo của C đã quan tâm đến tính di động - phần lớn Unix được viết bằng C, không giống như trước đây, khi các hệ điều hành được viết bằng bộ lắp ráp. Vì vậy, họ không muốn đối phó với mỗi nền tảng quirks về văn bản đại diện, vì vậy họ thêm hack ác này vào thư viện I/O của họ tùy thuộc vào nền tảng, đầu vào và đầu ra cho tập tin đó sẽ được "vá" trên bay để chương trình sẽ thấy các dòng mới chính xác, Unix-way - as '\ n' - cho dù đó là '\ r \ n' từ Windows hay '\ r' từ Mac. Vì vậy, các nhà phát triển không cần phải lo lắng về những gì hệ điều hành chương trình chạy, nó vẫn có thể đọc và ghi các tập tin văn bản ở định dạng gốc.
Có một vấn đề, tuy nhiên - không phải tất cả các tệp đều là văn bản, có các định dạng khác và chúng rất nhạy cảm để thay thế một ký tự với một ký tự khác. Vì vậy, họ mặc dù, chúng tôi sẽ gọi những "tệp nhị phân" và chỉ ra rằng để fopen()
bằng cách bao gồm 'b' trong chế độ - và điều này sẽ gắn cờ thư viện không thực hiện bất kỳ chuyển đổi hậu trường nào. Và đó là cách nó đã trở thành con đường của nó :)
Vì vậy, để tóm tắt lại, nếu tệp mở bằng 'b' ở chế độ nhị phân, sẽ không có chuyển đổi nào diễn ra. Nếu nó được mở trong chế độ văn bản, tùy thuộc vào nền tảng, một số chuyển đổi của (các) ký tự dòng mới có thể xảy ra - theo hướng nhìn của Unix. Đương nhiên, trên nền tảng Unix không có sự khác biệt giữa đọc/ghi vào "văn bản" hoặc "tệp nhị phân".
Vì vậy, nếu tôi đọc tệp văn bản Windows với python trên Linux, không có chuyển đổi nào xảy ra và tôi sẽ kết thúc bằng một \ r bổ sung trên mỗi dòng? –
Có. [lorem ipsum] – Thomas
@Fabian: vâng. Ứng dụng của bạn phải biết loại tệp nào cần xử lý. Trong hầu hết các trường hợp, bạn có thể chỉ cần kiểm tra nội dung tệp đã đọc cho các chuỗi "\ r \ n" và thay thế bằng "\ n" bằng cách sử dụng các phương thức chuỗi. – jsbueno