Что такое EOF для двоичных файлов? Состояние? Символ?
Я до сих пор справлялся с тем, что EOF
- специальный символ, автоматически вставленный в конце текстового файла, чтобы указать его конец. Но теперь я чувствую необходимость в некоторых разъяснениях по этому поводу. Я проверил на Google и на странице Википедии EOF
, но они не смогли ответить на следующее, и для этого нет точных ссылок. Поэтому, пожалуйста, помогите мне в этом:
-
В моей книге говорится, что файлы двоичного режима отслеживают конец файла из числа символов, присутствующих в записи каталога файла. (В отличие от текстовых файлов, которые имеют специальный символ EOF для обозначения конца). Итак, какова история EOF
в контексте двоичных файлов? Я запутался, потому что в следующей программе я успешно использую сравнение !=EOF
при чтении из файла .exe
в двоичном режиме:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int ch;
FILE *fp1,*fp2;
fp1=fopen("source.exe","rb");
fp2=fopen("dest.exe","wb");
if(fp1==NULL||fp2==NULL)
{
printf("Error opening files");
exit(-1);
}
while((ch=getc(fp1))!=EOF)
putc(ch,fp2);
fclose(fp1);
fclose(fp2);
}
-
Является ли EOF
особым "символом" вообще? Или это условие , как говорит Википедия, условие, когда компьютер знает, когда возвращать определенное значение, например -1
(EOF
на моем компьютере)? Пример такого "условия", когда функция считывания символов заканчивает чтение всех присутствующих символов или когда функции ввода/вывода символов/строк сталкиваются с ошибкой при чтении/записи?
Интересно, что тег для EOF
смешивал оба определения EOF
. Тег для EOF
сказал: "В области программирования EOF представляет собой последовательность байтов (или chacracter), которая указывает, что после этого больше нет содержимого". В то же время в разделе "about" также сказано, что "Конец файл (обычно сокращенный EOF) является условием в операционной системе компьютера, где больше данных не может быть прочитано из источника данных. Источник данных обычно называют файлом или потоком.
Но у меня сильное чувство, что EOF
не будет символом, поскольку каждая другая функция, кажется, возвращает его, когда он сталкивается с ошибкой во время ввода-вывода.
Будет очень мило с вашей стороны, если вы сможете очистить этот вопрос для меня.
Ответы
Ответ 1
Различные индикаторы EOF, которые предоставляет вам C, не обязательно имеют какое-либо отношение к тому, как файловая система отмечает конец файла.
Большинство современных файловых систем знают длину файла, потому что они записывают его где-то отдельно от содержимого файла. Подпрограммы, которые читают файл, отслеживают, где вы читаете, и останавливаются, когда вы достигаете конца. Подпрограммы библиотеки C генерируют значение EOF для возврата к вам; они не возвращают значение, которое фактически находится в файле.
Обратите внимание, что EOF, возвращаемый подпрограммами библиотеки C, на самом деле не является символом. Обычно в библиотечных подпрограммах C возвращается int
, а int
- или значение символа или EOF. Например, в одной реализации символы могут иметь значения от 0 до 255, а EOF может иметь значение -1. Когда библиотечная процедура столкнулась с концом файла, на самом деле она не увидела символ -1, потому что такого символа нет. Вместо этого в основной системной программе было сказано, что конец файла был достигнут, и он ответил, возвратив вам -1.
Старые и грубые файловые системы могут иметь значение в файле, который отмечает конец файла. По разным причинам это обычно нежелательно. В своей простейшей реализации это делает невозможным сохранение произвольных данных в файле, потому что вы не можете хранить маркер конца файла в качестве данных. Однако можно было реализовать реализацию, в которой необработанные данные в файле содержат то, что указывает на конец файла, но данные преобразуются при чтении или записи, чтобы можно было сохранить произвольные данные. (Например, путем "цитирования" маркера конца файла.)
В некоторых случаях такие элементы, как маркеры конца файла, также отображаются в потоках. Это обычно при чтении с терминала (или псевдотерминального или терминального устройства). В Windows нажатие кнопки управления-Z указывает на то, что пользователь выполнил ввод ввода, и он обрабатывается аналогично для достижения конца файла. Это не означает, что управление-Z является EOF. Чтение программного обеспечения с терминала видит control-Z, рассматривает его как конец файла и возвращает показания конца файла, которые, вероятно, отличаются от control-Z. В Unix контроль-D обычно похож на аналогичную часовую, обозначающую конец ввода.
Ответ 2
Это должно быть хорошо для вас.
В принципе, EOF - это просто макрос с предопределенным значением, представляющим код ошибки из функций ввода/вывода, указывающий на то, что больше нет данных для чтения.
Ответ 3
В файле фактически нет EOF. EOF не является символом сортировки - помните, что байт может быть между 0 и 255, поэтому не имеет смысла, если файл может содержать -1. EOF - это сигнал от используемой операционной системы, которая указывает, что конец файла достигнут. Обратите внимание, как getc() возвращает int
- это значит, что он может вернуть это -1, чтобы сообщить вам, что поток достиг конца файла.
Сигнал EOF обрабатывается одинаковым для двоичных и текстовых файлов - фактическое определение бинарного и текстового потоков зависит от ОС (например, в двоичном и двоичном режимах * nix - одно и то же.) В любом случае, как указано выше, он не является частью самого файла. OS передает его getc(), чтобы сообщить программе, что конец потока достигнут.
От
Ответ 4
EOF
не является символом. В этом контексте он -1, который технически не является персонажем (если вы хотите быть предельно точным, можно утверждать, что он может быть персонажем, но это не имеет значения в этом обсуждении). EOF
, просто для того, чтобы быть понятным - это "Конец файла". Пока вы читаете файл, вам нужно знать, когда остановиться, иначе может произойти ряд вещей в зависимости от среды, если вы попытаетесь прочитать за ним конец файла.
Итак, был разработан макрос, чтобы сообщить, что End of File был достигнут в процессе чтения файла, который равен EOF
. Для getc
это работает, потому что возвращает int
, а не char
, поэтому есть дополнительная комната, чтобы вернуть что-то, отличное от char
, в сигнал EOF
. Другие вызовы ввода/вывода могут сигнализировать EOF
по-разному, например, путем исключения исключения.
Как точка интереса, в DOS (и, возможно, еще в Windows?) фактический физический символ ^Z
был помещен в конец файла, чтобы сигнализировать о его окончании. Итак, в DOS на самом деле был символ EOF
. У Unix никогда не было такого.