9.3. Файловая обработка
Раздел 9. Алгоритмы и программирование (продолжение)
📋 Содержание темы:
Основы работы с файлами
Файл — именованная область памяти на диске для хранения данных.
Режимы открытия файлов:
| Режим | Описание |
|---|---|
'r' | Чтение (по умолчанию). Файл должен существовать. |
'w' | Запись. Файл перезаисывается или создаётся. |
'a' | Дописывание в конец файла. |
'r+' | Чтение и запись. Файл должен существовать. |
'rb' | Чтение бинарного файла. |
'wb' | Запись бинарного файла. |
Открытие и закрытие файла:
# Способ 1: ручное открытие и закрытие
f = open("data.txt", "r")
content = f.read()
f.close()
# Способ 2: контекстный менеджер (рекомендуется)
with open("data.txt", "r") as f:
content = f.read()
Важно: Всегда используйте
with — файл автоматически закрывается даже при ошибке.Текстовые файлы
Чтение текстового файла:
# Прочитать весь файл целиком
with open("data.txt", "r", encoding="utf-8") as f:
text = f.read()
print(text)
# Прочитать построчно
with open("data.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip() убирает \n
# Прочитать все строки в список
with open("data.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines)
Запись в текстовый файл:
# Записать строку
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Привет, мир!\n")
# Записать несколько строк
lines = ["Первая строка\n", "Вторая строка\n", "Третья строка\n"]
with open("output.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
# Записать через print
with open("output.txt", "w", encoding="utf-8") as f:
print("Значение:", 42, file=f)
Дописывание в файл:
# Добавить строки в конец файла
with open("log.txt", "a", encoding="utf-8") as f:
f.write("Новая запись\n")
Бинарные файлы
Бинарные файлы хранят данные в формате, не предназначённом для чтения человеком (изображения, архивы, программные файлы).
Чтение и запись бинарных данных:
# Копирование бинарного файла
with open("image.jpg", "rb") as f_in:
data = f_in.read()
with open("copy.jpg", "wb") as f_out:
f_out.write(data)
# Запись числовых данных в бинарный файл
import struct
with open("numbers.bin", "wb") as f:
for num in [10, 20, 30, 40, 50]:
f.write(struct.pack('i', num)) # 'i' — целое число
Чтение бинарных чисел:
import struct
with open("numbers.bin", "rb") as f:
while True:
data = f.read(4) # 4 байта на число
if not data:
break
num = struct.unpack('i', data)[0]
print(num)
Обработка CSV-файлов
CSV (Comma-Separated Values) — формат для хранения табличных данных.
Пример CSV-файла:
Имя;Возраст;Оценка Анна;15;5 Борис;16;4 Вера;15;5
Чтение CSV без модуля:
with open("students.csv", "r", encoding="utf-8") as f:
header = f.readline().strip().split(";")
students = []
for line in f:
values = line.strip().split(";")
student = dict(zip(header, values))
students.append(student)
print(students)
# [{'Имя': 'Анна', 'Возраст': '15', 'Оценка': '5'}, ...]
Чтение CSV с модулем csv:
import csv
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f, delimiter=';')
for row in reader:
print(f"{row['Имя']}: {row['Оценка']}")
Запись в CSV:
import csv
data = [
{"Имя": "Глеб", "Возраст": 16, "Оценка": 5},
{"Имя": "Дина", "Возраст": 15, "Оценка": 4}
]
with open("new_students.csv", "w", encoding="utf-8", newline='') as f:
writer = csv.DictWriter(f, fieldnames=["Имя", "Возраст", "Оценка"],
delimiter=';', quoting=csv.QUOTE_MINIMAL)
writer.writeheader()
writer.writerows(data)
Практические задачи
Задача 1: Подсчёт слов в файле
def count_words(filename):
"""Подсчитывает количество каждого слова в файле."""
with open(filename, "r", encoding="utf-8") as f:
text = f.read().lower()
# Убираем знаки препинания
for char in ".,!?;:-()\"'":
text = text.replace(char, "")
words = text.split()
count = {}
for word in words:
count[word] = count.get(word, 0) + 1
return count
result = count_words("text.txt")
for word, n in sorted(result.items(), key=lambda x: -x[1])[:10]:
print(f"{word}: {n}")
Задача 2: Фильтрация данных из файла
def filter_grades(input_file, output_file, min_grade):
"""Сохраняет учеников с оценкой >= min_grade."""
with open(input_file, "r", encoding="utf-8") as f_in:
header = f_in.readline()
with open(output_file, "w", encoding="utf-8") as f_out:
f_out.write(header)
for line in f_in:
parts = line.strip().split(";")
if int(parts[2]) >= min_grade:
f_out.write(line)
filter_grades("students.csv", "excellent.csv", 5)
Задача 3: Слияние двух отсортированных файлов
def merge_files(file1, file2, output):
"""Сливает два отсортированных числовых файла."""
with open(file1) as f1, open(file2) as f2:
nums1 = sorted([int(x) for x in f1.read().split()])
nums2 = sorted([int(x) for x in f2.read().split()])
merged = sorted(nums1 + nums2)
with open(output, "w") as f:
f.write(" ".join(map(str, merged)))
Задача 4: Шифр Цезаря для файла
def caesar_cipher(text, shift):
"""Шифр Цезаря: сдвигает каждую букву на shift позиций."""
result = ""
for char in text:
if 'а' <= char <= 'я':
code = ord(char) - ord('а')
new_code = (code + shift) % 32
result += chr(ord('а') + new_code)
elif 'А' <= char <= 'Я':
code = ord(char) - ord('А')
new_code = (code + shift) % 32
result += chr(ord('А') + new_code)
else:
result += char
return result
# Зашифровать файл
with open("plain.txt", "r", encoding="utf-8") as f:
text = f.read()
with open("encrypted.txt", "w", encoding="utf-8") as f:
f.write(caesar_cipher(text, 3))
Внимание: При работе с файлами всегда указывайте кодировку
encoding="utf-8" для корректного отображения русских символов.