Можем ли мы сами написать персонаж EOF? - PullRequest
37 голосов
/ 17 июня 2010

В большинстве языков, таких как C ++, при записи в файл ставьте символ EOF, даже если мы пропускаем такие операторы, как:

filestream.close

Однако есть ли способ, мы можем поместить символ EOF согласно нашему требованию, в C ++, для экземпляра. Или любой другой метод, который мы можем использовать, кроме функций, предоставляемых в C ++.

Если вам нужно больше информации, просим дать комментарий.

Заранее спасибо.

РЕДАКТИРОВАТЬ: Спасибо за вашу поддержку, но вот дополнение к этому вопросу:

Что делать, если мы хотим обмануть ОС и поместить символ EOF в файл и записать некоторые данные после EOF, чтобы такое приложение, как notepad.exe, не могло читать после нашего символа EOF. Я прочитал ответы на вопрос, связанный с этой темой, и узнал, что в настоящее время ОС обычно не видит символа EOF, а скорее проверяет длину файла, чтобы получить правильное представление о длине файла, но там должна быть процедура в ОС, которая будет проверять длину файла и затем обновлять записи файла.

Извините, если я ошибаюсь в какой-то момент в моей оценке, но, пожалуйста, помогите мне, потому что это может привести ко множеству новых идей.

Ответы [ 9 ]

49 голосов
/ 17 июня 2010

EOF-персонажа нет.EOF по определению "неравен любому действительному символьному коду".Часто это -1.Он никогда не записывается в файл.

В DOS существует историческое значение символа EOF (CTRL + Z), но в наши дни оно устарело.

Ответитьследующий вопрос Apoorv: ОС никогда не использует данные файла для определения длины файла (файлы не имеют нулевого завершения).Таким образом, вы не можете обмануть ОС.Возможно, старые глупые программы не будут читать после символа CTRL + Z.Я не предполагал бы, что любое приложение Windows (даже Блокнот) сделало бы это.Я предполагаю, что было бы легче обмануть их нулевым (\0) символом.

13 голосов
/ 17 июня 2010

Ну, EOF - это просто значение, возвращаемое функцией, определенной в заголовочном файле C stdio.h.Он фактически возвращается ко всем функциям чтения ОС, поэтому его системная зависимость.Когда ОС достигает конца файла, она отправляет его в функцию, которая в своем возвращаемом значении больше, чем обычно (-1), но не всегда.Итак, подведем итог: EOF это не символ, а константа, возвращаемая ОС.РЕДАКТИРОВАТЬ: Ну, вам нужно больше узнать о файловой системе, посмотрите на это.

Привет, на ваш второй вопрос:

еще раз, вы должны лучше посмотреть в filesystems.FAT - очень хороший пример, потому что вы можете найти много статей об этом, и его принципы очень похожи на NTFS.Во всяком случае, еще раз, EOF NOT a character.Вы не можете поместить его в файл напрямую.Если бы вы могли сделать это, представьте себе последствия, даже «тупой» файл изображения не может быть прочитан системой.

Почему?Поскольку ОС работает как очень сложная структура слоев.Одним из уровней является драйвер файловой системы.Он обеспечивает передачу данных из каждой файловой системы, известной драйверу.Он обеспечивает связь между приложениями и действующей системой хранения файлов на жестком диске.

Если быть точным, файловая система FAT использует так называемую таблицу FAT - это таблица, расположенная рядом с началом жесткого диска (или раздела).адресное пространство, и оно содержит карту всех кластеров (маленькие ячейки памяти).Итак, теперь, когда вы хотите сохранить какой-либо файл на жесткий диск, ОС (драйвер файловой системы) просматривает таблицу FAT и ищет значение «0x0».Это значение «0x0» сообщает ОС, что кластер, адрес которого описывается расположением этого значения в таблице FAT, может свободно записывать.

Итак, он записывает в него первую часть файла.Затем он ищет другое значение «0x0» в FAT и, если он найден, записывает вторую часть файла в кластер, на который он указывает.Затем он изменяет значение первой записи таблицы FAT, в которой находится файл, на физический адрес следующей, в нашем случае, второй части файла.

Когда ваш файл хранится на жестком диске, теперь появляется последняя часть, он записывает желаемое значение EOF, но в таблицу FAT, а не в «часть данных» жесткого диска.Поэтому, когда файл читается в следующий раз, он знает, что это конец, не смотрите дальше.

Итак, теперь вы видите, хотите ли вы вручную записать значение EOF в место, где он находится?Для этого вам нужно написать свой собственный драйвер, который сможет переписать запись FAT, но это практически невозможно сделать для начинающих.

12 голосов
/ 16 декабря 2012

Я пришел сюда во время выполнения упражнений Кернигана и Ричи C .

Ctrl + D отправляет символ, соответствующий EOF константа от stdio.h.

(Редактировать: это в Mac OS X; спасибо @markmnl за то, что указал, что эквивалент Windows 10 равен Ctrl + Z )

7 голосов
/ 17 июня 2010

На самом деле в C ++ отсутствует физический символ EOF, записываемый в файл с использованием механизмов fprintf () или ostream.EOF - это условие ввода-вывода, указывающее, что больше нет данных для чтения.

Некоторые ранние дисковые операционные системы, такие как CP / M, фактически использовали физический 0x1A (символ ASCII SUB) для обозначения EOF, поскольку файловая система поддерживается толькоразмер файла в блоках, так что вы никогда не знали точно, как долго файл был в байтах.С появлением в каталоге фактических значений длины больше не является типичным хранение символа «EOF» как части данных внутриполосного файла.

5 голосов
/ 13 ноября 2013

В Windows, если вы встретите ASCII 26 (EOF) в stdin, он прекратит чтение остальных данных.Я полагаю, что написание этого символа также прекратит вывод, отправленный на стандартный вывод, но я не подтвердил это.Вы можете переключить поток в двоичный режим , как в этом вопросе SO :

#include <io.h>
#include <fcntl.h>
...
_setmode(0, _O_BINARY)

И вы не только остановите преобразование 0x0A в 0x0D 0x0A, но и получитечитать / писать также 0x1A.Обратите внимание, что вам, возможно, придется переключить как stdin (0), так и stdout (1).

4 голосов
/ 30 мая 2013

Нет такой вещи как символ "EOF".Сам факт закрытия потока является условием «EOF».

Когда вы нажимаете Ctrl + D в оболочке Unix, которая просто закрывает стандартный вводПоток, который, в свою очередь, распознается оболочкой как «EOF» и выходит.

Итак, чтобы «отправить» «EOF», просто закройте поток, в который необходимо отправить «EOF».

4 голосов
/ 17 июня 2010

Если под символом EOF вы подразумеваете что-то вроде Control-Z, то современные операционные системы не нуждаются в этом, и среда выполнения C ++ не напишет для вас. Вы, конечно, можете написать самостоятельно:

 filestream.put( 26 );     // write Ctrl-Z

но нет веских причин для этого. Также нет необходимости делать:

 filesystem.close();

поскольку поток файлов будет закрыт для вас автоматически при вызове деструктора, но это (я думаю) хорошая практика для этого.

3 голосов
/ 30 сентября 2013

Никто еще не упомянул системные вызовы [f]truncate, которые позволяют сократить размер файла, не создавая его заново.

Функции truncate() и ftruncate() приводят к усечению обычного файла с именем path или ссылкой fd до размера точно length байт.

Если файл ранее был больше этого размера, лишние данные будут потеряны. Если файл ранее был короче, он расширяется, и расширенная часть читается как нулевые байты ('\0').

Поймите, что это отличная операция от записи любых данных в файл. Файл представляет собой линейный массив байтов, каким-либо образом размещенный на диске, с метаданными, указывающими, как долго это происходит; truncate меняет метаданные.

2 голосов
/ 17 июня 2010

В современных файловых системах EOF не является символом, поэтому вам не нужно выдавать его при завершении записи в файл. Вам просто нужно закрыть файл или позволить ОС сделать это за вас, когда ваш процесс завершится.

...