Файлы

Файл - это набор данных во внешней памяти, имеющий имя. 

В Python существует два типа файлов:
- текстовые, который содержит текст, разбитый на строке; из специальных символов в текстовых файлах могут быть только символы перехода на новую строку ("\n") и возврата в начало строки ("\r");
- двоичные, в которых хранятся любые двоичные данные без ограничений (например, рисунки, звуки, видеофильмы и т.д.).

Далее будем рассматривать работу с текстовыми файлами.

 

Принцип работы с файлом из программы
Состоит из трех этапов:
1. открытие файла;
2. работа с файлом;
3. закрытие файла.
Такой принцип работы называют "принципом сэндвича".

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

Функция open() позволяет открыть файл и возвращает файловую переменную, через которую можно обращаться к файлу.
f = open(file_name, access_mode)
где:
- file_name - имя открываемого файла
- access_mode - режим открытия файла. Он может быть: для чтения, записи и т. д. По умолчанию используется режим чтения (r), если другое не указано. 
 
Полный список режимов открытия файла
Режим Описание
r Только для чтения.
w Только для записи. Создаст новый файл, если не найдет с указанным именем.
rb Только для чтения (бинарный).
wb Только для записи (бинарный). Создаст новый файл, если не найдет с указанным именем.
r+ Для чтения и записи.
rb+ Для чтения и записи (бинарный).
w+ Для чтения и записи. Создаст новый файл для записи, если не найдет с указанным именем.
wb+ Для чтения и записи (бинарный). Создаст новый файл для записи, если не найдет с указанным именем.
a Откроет для добавления нового содержимого. Создаст новый файл для записи, если не найдет с указанным именем.
a+ Откроет для добавления нового содержимого. Создаст новый файл для чтения записи, если не найдет с указанным именем.
ab Откроет для добавления нового содержимого (бинарный). Создаст новый файл для записи, если не найдет с указанным именем.
ab+ Откроет для добавления нового содержимого (бинарный). Создаст новый файл для чтения записи, если не найдет с указанным именем.

 
Метод close() позволяет закрыть файл.

Пример
Fin = open("input.txt")
Fout = open("output.txt")
   # что-то делаем с файлами
Fout.close()
Fin.close()
Если существующий файл открывается на запись, то его содержимое уничтожается. После окончания работы программы все открытые файлы закрываются автоматически.
 

Чтение данных из файла

При чтении текстового файла, поток байтов поступает на вход программы последовательно один за другим, поэтому файл обеспечивает последовательный доступ к данным. То есть, если нам необходимо прочитать 10-е по счету значение из файла, необходимо сначала прочитать предыдущие 9.

Чтение одной строки файла позволяет выполнять метод readline(). Вызывается данный метод для файловой переменной.
Fin = open("input.txt")
s = Fin.readline()

К считываемой строке можно применять различные методы, аналогичные тем, которые применяли при считывании с клавиатуры (split(), map() и пр.). Например, если в строке файла находятся два числа через пробел, то считать их можно следующим образом:
Fin = open("input.txt")
s = Fin.readline().split() # разбили строку по пробелам s = ["2007", "2021"]
a, b = map(int, s)         # ко всем элементам списка s применяем метод int(), 
                           # то есть преобразуем символьную строку в число
# a, b = int(s[0], s[1])   # это то же самое, что и строкой выше
# a, b = [int(x) for x in s] # то же самое только в виде генератора

Метод read() считывает все содержимое из файла и возвращает строку, которая может содержать символы '\n'. Если методу read() передать целочисленный параметр, то будет считано не более заданного количества символов. Например, считывать файл побайтово можно при помощи метода read(1).

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

 
Примечение
При работе в онлайн-компиляторе, который отоюражается при решении задачи, файл находится в том же месте куда сохраняется программа при запуске. Таким образом, для доступа к этому файлу в методе open достаточно указать имя файла (без указания пути). Например, для файла input.txt можно написать просто Fin = open("input.txt"). Имя файла, которое доступно для чтения и которое можно использовать в онлайн компиляторе указано в первой строке.

Запись данных в файл

Для записи данных в файл используется метод write(). Числовые данные необходимо преобразовывать в строку. Сделать это можно либо методом format(), либо методом str().

 

Многострочные файлы

При работе с многострочными файлами, необходимо узнать, когда данные в файле закончатся. Для этого можно использовать особенность работы методы readline(): если файловый курсор указывает на конец файла, то метод readline() возвращает пустую строку, которая воспринимается как ложное логическое значение:
while True:
    s = Fin.readline()
    if not s: break   # если при считывании строки получена пустая строка, 
                      # цикл заканчивается с помощью оператора break
    print(s, end="")  # переход на новую строку отключаем, так как при считывании строки из файла 
                      # символ перевода на новую строку "\n" сохраняется

 

Другие способы считывания данных из многострочных файлов
1. Сразу все данные в список.
Fin = open("input.txt")
list_strings = Fin.readlines()    # считали сразу все строки
Fin.close()
for s in list_strings:
    print(s, end="")

2. С использованием конструкции with-as. В данном случае файл закрывается автоматически после окончания цикла.
with open("input.txt") as Fin:
    for s in Fin:
        print(s, end="")
Эта конструкция гарантирует, что файл будет закрыт. 


3. Способ перебора строк в стиле языка Python (рекомендуется использовать данный способ). В данном случае файл также закрывается автоматически.
for s in open("input.txt"):
    print(s, end="")

Файл с кириллицей

Если в файле есть русские буквы (любой символ с кодом, большим 127), то необходимо при открытии указывать кодировку
data = open("input.txt", "r", encoding="utf-8")