C: Как реализован бинарный режим по сравнению с текстовым режимом для fopen?

В качестве учебного упражнения я пытаюсь написать уровень платформы на C для операционных систем Windows и GNU/Linux.

В настоящее время меня интересует реализация функции, которая открывает файл на хост-платформе в предоставленном режиме, аналогично fopen из <stdio.h>. Я знаю, что есть функция Windows API CreateFile из <fileapi.h> и функция GNU open из <fcntl.h>; Я думаю, что смогу использовать их, чтобы открыть файл с диска для чтения или записи. Однако fopen также обеспечивает выбор режима открытия файла: в двоичном или текстовом режиме. Я не совсем понимаю, в чем разница между этими работами под капотом; как мне реализовать эту функциональность в моей версии?

В posix/linux/*BSD разницы нет. Это просто то, как fgets интерпретирует строку текста. В Linux терминатор строки — \n (новая строка/0x0A). В Windows терминатор строки — \r\n (crlf, cr/newline, 0x0D/0x0A). Если вы передадите b (для двоичного кода) в fopen, он добавит O_BINARY к флагам, данным [базовому] вызову open (или эквиваленту Win32). В Linux уровень приложения (например, fgets) обрабатывает признак конца строки. Я не могу вспомнить точный механизм, но Windows обрабатывает это в ядре. Чтение низкого уровня будет работать по-разному в зависимости от режима.

Craig Estey 23.02.2024 21:10

Под окнами с помощью O_BINARY вы увидите \r\n. Без него (т. е. O_TEXT) \r\n массируется до \n на лету. Повторяю, на Linux et. ал. b и O_BINARY не используются и предусмотрены для совместимости с Win32.

Craig Estey 23.02.2024 21:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
133
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В Microsoft Windows текстовые файлы обычно используют символы \r\n (возврат каретки с последующим переводом строки) в качестве окончания строки. При чтении файлов, открытых в текстовом режиме, окончания строк \r\n преобразуются в \n, так что приложению кажется, что окончания строк состоят из \n вместо \r\n. Кроме того, при записи файлов в текстовом режиме окончания строк \n преобразуются в \r\n. Эти переводы не происходят в двоичном режиме. Кроме того, значение байта 0x1A интерпретируется как конец файла в текстовом режиме, а не в двоичном.

Однако в GNU/Linux (и на всех других платформах POSIX) нет разницы между текстовым и двоичным режимом. В обоих режимах перевод не осуществляется. Это связано с тем, что на этой платформе окончания строк текстовых файлов изначально состоят только из \n, поэтому перевод не требуется.

На самом деле, «окончание строк» ​​предполагает очень многое. Это двухбайтовая последовательность CRLF, преобразованная в LF при чтении, и LF, преобразованная в CRLF при записи... Бедный человек, который пренебрег указанием «b» при открытии файла (двоичных данных или текста), может рассчитывать на сверхурочную работу, чтобы найти Устраните проблему, которая может выглядеть как «поврежденные данные».

Fe2O3 23.02.2024 21:52

В оригинальной Mac OS (когда она называлась «Система») и некоторых других малоизвестных ОС, таких как OS/9, конец строки равен \r.

John Bayko 24.02.2024 01:14
Ответ принят как подходящий

не совсем понимаю, в чем разница между этими работами под капотом;

Когда код использует "b" для открытия файла, перевод отсутствует. Что бы ни было в файле, это то, что читается. Все, что записано в файл, записывается.

Если код не использует "b" для открытия файла, существует потенциальный перевод. Исходящий "\n" может быть переведен в "\r\n", "\r", "\n" или что-то еще. В последней записи может быть добавлен Ctrl z или нет. Начало файла может включать Спецификацию. Возможны и другие переводы. Чтение таких файлов может потребовать упомянутого выше и предоставить код с меньшим количеством информации. Существует множество аспектов реализации чтения и записи такого текстового файла.

При чтении/записи текстового файла не используйте "b". В противном случае не открывайте с помощью "b".


как мне реализовать эту функциональность в моей версии?

При чтении текстового файла не используйте "b", в противном случае используйте "b".

Другие вопросы по теме