Файл. Функциональная спецификация: последовательность, которая живет дольше программы

Модуль "Файл и вектор" • урок 1 из 6 • ~6 минут

Суть урока. Файл - долговременный динамический объект: конечная последовательность компонент одного типа со строго последовательным доступом. Его множество значений задается порождающими правилами: пустая последовательность - файл; файл с дописанной в конец компонентой - тоже файл. Прочитать сотую компоненту, не прочитав 99 предыдущих, нельзя.
Файл. Функциональная спецификация: строго последовательный доступ к компонентам
Файл как последовательность компонент

Что это такое

Файл - динамический объект, состоящий из последовательности компонент одного типа. От структур в оперативной памяти его отличает главное: время жизни файла обычно превышает время жизни породившей его программы. Программа завершилась - файл остался, у него есть собственное имя в операционной системе.

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

Порождающие правила

Множество значений файлового типа - конечные последовательности компонент. Формально его задают три правила:

  1. {} - пустая последовательность - является файлом.
  2. Если f - файл, а t - компонента, то результат приписывания t в конец f (операция конкатенации) - тоже файл.
  3. Никакие другие значения файлами не являются.

Обратите внимание: определение рекурсивно - каждый непустой файл получается из файла поменьше дописыванием одной компоненты. Никакого способа вставить компоненту в середину правила не дают: файл растет только с конца.

Базовые атрибуты файлового типа

Про доступ стоит сказать отдельно - это главная особенность файла. Он строго последовательный: чтобы прочитать k-ю компоненту, нужно сначала прочитать k - 1 предыдущих. Как магнитная лента: перемотать сразу к нужному месту нельзя, лента проматывается вся.

А как в Python? Файл открывается функцией open() и читается по строкам - удобный итерируемый объект. Но математически он тот же: абстрактная последовательность строк или байтов, которую читают одну за другой и в конец которой дописывают (режим "a", append, - это та самая конкатенация из спецификации).

Спецификация в функциях C

Файл. Функциональная спецификация в стандартной библиотеке

Абстрактные функции спецификации узнаются в стандартной библиотеке:

#include <stdio.h>

int main(void) {
    /* СОЗДАТЬ: на уровне C файл - это поток (stream) */
    FILE *f = fopen("test.txt", "w");
    if (f) {
        /* МОДИФИКАЦИЯ: дозапись компонент в конец последовательности */
        fputc('A', f);
        fputc('B', f);
        fclose(f);
    }
    return 0;
}

Как файл описывается в языках целиком и как он устроен на физических носителях - в следующем уроке.

Коротко: главное

  • Файл - долговременный динамический объект: живет дольше программы, имеет имя в ОС.
  • Это конечная последовательность компонент одного типа.
  • Порождающие правила: {} - файл; файл + компонента (конкатенация) - тоже файл.
  • Доступ строго последовательный: k-я компонента - только после k - 1 предыдущих.
  • Атрибуты: конкатенация, присваивание, равенство; создание, доступ, дозапись, уничтожение.

Проверьте себя

По функциональной спецификации файла: что нужно сделать, чтобы прочитать его сотую компоненту?

Как вам урок? Спасибо за отзыв!