Что такое 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 никогда не было такого.