Робота з файлами
Робота з файлами — це одна з найважливіших навичок у програмуванні. Файли дозволяють нам:
- Зберігати дані між запусками програми
- Обмінюватися інформацією з іншими програмами
- Обробляти великі обсяги даних, які не помістяться в пам'яті
- Створювати логи для відстеження роботи програми
- Читати конфігурації та налаштування
Базові концепції
Що таке файл? Файл — це іменована область на диску, яка містить дані. Файли можуть містити текст, числа, зображення, відео тощо.
Шляхи до файлів:
- Абсолютний шлях: повний шлях від кореневої директорії (
/Users/user/documents/file.txtабоC:\Users\user\documents\file.txt) - Відносний шлях: шлях відносно поточної директорії (
./data/file.txtабо простоfile.txt)
Режими відкриття файлів:
'r'— читання (read) — файл повинен існувати'w'— запис (write) — створює новий файл або перезаписує існуючий'a'— додавання (append) — додає до кінця файлу'r+'— читання та запис'b'— бінарний режим (додається до інших режимів:'rb','wb')'t'— текстовий режим (за замовчуванням)
Важливо знати:
- Завжди закривайте файли після роботи з ними
- Використовуйте
withдля автоматичного закриття файлів - Обробляйте виключення при роботі з файлами
- Кодування за замовчуванням — UTF-8 (для текстових файлів)
Відкрити файл для читання
Простий приклад
with open("example.txt", "r") as file: content = file.read() print(content) # Вміст файлу
Відкрити файл для запису
with open("example.txt", "w") as file: file.write("Привіт, світ!") # Файл example.txt містить: # Привіт, світ!
Додати інформацію у файл
with open("example.txt", "a") as file: file.write("\nНовий рядок додано") # Файл example.txt містить: # Привіт, світ! # Новий рядок додано
Прочитати весь файл
with open("example.txt", "r") as file: content = file.read() print(content) # Привіт, світ! # Новий рядок додано
Прочитати файл построково
with open("example.txt", "r") as file: for line in file: print(line.strip()) # Привіт, світ! # Новий рядок додано
Запис у файл (write, writelines)
lines = ["Рядок 1\n", "Рядок 2\n", "Рядок 3\n"] with open("output.txt", "w") as file: file.writelines(lines) # Файл output.txt містить: # Рядок 1 # Рядок 2 # Рядок 3
Закриття файлу
Усі операції з файлами, відкритими через with open, автоматично закривають файл після завершення блоку with. Якщо файл відкритий без використання with, його необхідно закривати вручну:
file = open("example.txt", "r") content = file.read() file.close()
Обробка виключень при роботі з файлами
try: with open("non_existent_file.txt", "r") as file: content = file.read() except FileNotFoundError: print("Файл не знайдено!") # Файл не знайдено!
Читання файлу різними способами
Метод read() — читання всього файлу
with open("data.txt", "r") as file: content = file.read() # Читає весь файл як один рядок print(content)
Метод read(n) — читання n символів
with open("data.txt", "r") as file: first_10_chars = file.read(10) # Читає перші 10 символів next_5_chars = file.read(5) # Читає наступні 5 символів print(first_10_chars) print(next_5_chars)
Метод readline() — читання одного рядка
with open("data.txt", "r") as file: line1 = file.readline() # Читає перший рядок line2 = file.readline() # Читає другий рядок print(line1.strip()) print(line2.strip())
Метод readlines() — читання всіх рядків у список
with open("data.txt", "r") as file: lines = file.readlines() # Повертає список всіх рядків print(lines) # ['Рядок 1\n', 'Рядок 2\n', 'Рядок 3\n']
Ітерація по файлу (найефективніший спосіб)
with open("large_file.txt", "r") as file: for line in file: # Читає по одному рядку (економить пам'ять) print(line.strip())
Запис у файл різними способами
Метод write() — запис рядка
with open("output.txt", "w") as file: file.write("Привіт, світ!\n") file.write("Це другий рядок\n") # Файл містить: # Привіт, світ! # Це другий рядок
Метод writelines() — запис списку рядків
lines = ["Перший рядок\n", "Другий рядок\n", "Третій рядок\n"] with open("output.txt", "w") as file: file.writelines(lines)
Запис з форматуванням
name = "Іван" age = 25 score = 95.5 with open("results.txt", "w") as file: file.write(f"Ім'я: {name}\n") file.write(f"Вік: {age}\n") file.write(f"Оцінка: {score}\n") # Файл містить: # Ім'я: Іван # Вік: 25 # Оцінка: 95.5
Режими відкриття файлів (детально)
Режим 'r+' — читання та запис
with open("data.txt", "r+") as file: content = file.read() # Спочатку читаємо file.write("\nНовий текст") # Потім пишемо в кінець
Режим 'w+' — запис та читання (перезапис файлу)
with open("data.txt", "w+") as file: file.write("Новий вміст\n") file.seek(0) # Повертаємося на початок файлу content = file.read() print(content) # Новий вміст
Режим 'a+' — додавання та читання
with open("log.txt", "a+") as file: file.write("Новий запис в лог\n") file.seek(0) # Повертаємося на початок all_logs = file.read() print(all_logs)
Робота з позицією в файлі
Метод seek() — переміщення позиції курсора
with open("data.txt", "r") as file: file.seek(10) # Переміститися на 10-й байт content = file.read() print(content)
Метод tell() — визначення поточної позиції
with open("data.txt", "r") as file: print(file.tell()) # 0 (початок файлу) file.read(10) print(file.tell()) # 10 (після читання 10 байт)
Переміщення відносно кінця файлу
with open("data.txt", "rb") as file: # Бінарний режим для seek з кінця file.seek(-10, 2) # -10 байт від кінця файлу content = file.read() print(content)
Робота з бінарними файлами
Читання бінарного файлу
with open("image.jpg", "rb") as file: binary_data = file.read() print(f"Розмір файлу: {len(binary_data)} байт")
Запис бінарного файлу
data = b'\x00\x01\x02\x03\x04' with open("binary_file.bin", "wb") as file: file.write(data)
Копіювання бінарного файлу
with open("source.jpg", "rb") as source: with open("copy.jpg", "wb") as destination: destination.write(source.read()) print("Файл успішно скопійовано!")
Робота з кодуванням
Вказівка кодування при відкритті файлу
# Читання файлу з кодуванням UTF-8 with open("ukrainian_text.txt", "r", encoding="utf-8") as file: content = file.read() print(content)
Робота з різними кодуваннями
# Запис з кодуванням UTF-8 with open("output.txt", "w", encoding="utf-8") as file: file.write("Привіт! Це текст українською мовою.") # Читання з кодуванням Windows-1251 with open("old_file.txt", "r", encoding="windows-1251") as file: content = file.read() print(content)
Перевірка існування файлу
Використання os.path
import os if os.path.exists("data.txt"): print("Файл існує") else: print("Файл не існує")
Використання pathlib (сучасний підхід)
from pathlib import Path file = Path("data.txt") if file.exists(): print("Файл існує") print(f"Розмір: {file.stat().st_size} байт") else: print("Файл не існує")
Перевірка перед відкриттям
import os filename = "important_data.txt" if os.path.exists(filename): with open(filename, "r") as file: content = file.read() print(content) else: print(f"Файл {filename} не знайдено!")
Робота з директоріями
Створення директорії
import os # Створити одну директорію if not os.path.exists("data"): os.mkdir("data") # Створити вкладені директорії os.makedirs("data/subfolder/nested", exist_ok=True)
Отримання списку файлів у директорії
import os files = os.listdir(".") # Поточна директорія print("Файли та папки:") for item in files: print(item)
Перебір файлів з фільтрацією
import os # Знайти всі .txt файли for filename in os.listdir("."): if filename.endswith(".txt"): print(f"Знайдено текстовий файл: {filename}")
Практичні приклади
Приклад 1: Лог-файл
from datetime import datetime def write_log(message): with open("app.log", "a") as log_file: timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_file.write(f"[{timestamp}] {message}\n") # Використання write_log("Програма запущена") write_log("Користувач увійшов в систему") write_log("Операція завершена успішно")
Приклад 2: Обробка CSV-подібних даних
# Запис даних студентів students = [ ["Іван", "Петренко", 20, 95], ["Марія", "Коваленко", 19, 88], ["Олег", "Сидоренко", 21, 92] ] with open("students.csv", "w") as file: file.write("Ім'я,Прізвище,Вік,Оцінка\n") for student in students: line = ",".join(map(str, student)) file.write(line + "\n") # Читання даних студентів with open("students.csv", "r") as file: header = file.readline().strip() print(f"Заголовок: {header}") for line in file: data = line.strip().split(",") print(f"Студент: {data[0]} {data[1]}, Вік: {data[2]}, Оцінка: {data[3]}")
Приклад 3: Підрахунок статистики тексту
def analyze_text_file(filename): try: with open(filename, "r", encoding="utf-8") as file: content = file.read() # Підрахунок статистики lines = content.split("\n") words = content.split() chars = len(content) print(f"Статистика файлу '{filename}':") print(f" Рядків: {len(lines)}") print(f" Слів: {len(words)}") print(f" Символів: {chars}") except FileNotFoundError: print(f"Файл '{filename}' не знайдено!") # Використання analyze_text_file("essay.txt")
Приклад 4: Фільтрація та обробка даних
# Читання числових даних та фільтрація def filter_numbers(input_file, output_file, threshold): with open(input_file, "r") as infile: numbers = [] for line in infile: try: num = float(line.strip()) if num > threshold: numbers.append(num) except ValueError: continue with open(output_file, "w") as outfile: for num in numbers: outfile.write(f"{num}\n") print(f"Відфільтровано {len(numbers)} чисел більших за {threshold}") # Використання filter_numbers("data.txt", "filtered.txt", 50)
Приклад 5: Резервне копіювання файлу
import shutil from datetime import datetime def backup_file(filename): try: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") backup_name = f"{filename}.backup_{timestamp}" shutil.copy2(filename, backup_name) print(f"Створено резервну копію: {backup_name}") except FileNotFoundError: print(f"Файл '{filename}' не знайдено!") except Exception as e: print(f"Помилка при створенні копії: {e}") # Використання backup_file("important_data.txt")
Приклад 6: Пошук тексту у файлі
def search_in_file(filename, search_term): try: with open(filename, "r", encoding="utf-8") as file: line_number = 0 found_count = 0 for line in file: line_number += 1 if search_term.lower() in line.lower(): print(f"Рядок {line_number}: {line.strip()}") found_count += 1 if found_count == 0: print(f"Текст '{search_term}' не знайдено") else: print(f"\nЗнайдено {found_count} збігів") except FileNotFoundError: print(f"Файл '{filename}' не знайдено!") # Використання search_in_file("document.txt", "Python")
Приклад 7: Об'єднання декількох файлів
def merge_files(input_files, output_file): with open(output_file, "w") as outfile: for filename in input_files: try: with open(filename, "r") as infile: outfile.write(f"\n--- Вміст з {filename} ---\n") outfile.write(infile.read()) outfile.write("\n") print(f"Додано вміст з '{filename}'") except FileNotFoundError: print(f"Файл '{filename}' не знайдено, пропускаємо...") print(f"\nВсі файли об'єднано в '{output_file}'") # Використання files_to_merge = ["part1.txt", "part2.txt", "part3.txt"] merge_files(files_to_merge, "complete.txt")
Робота з JSON файлами
Запис у JSON файл
import json # Дані для збереження data = { "name": "Іван Петренко", "age": 25, "city": "Київ", "hobbies": ["читання", "спорт", "програмування"] } # Запис у JSON файл with open("user_data.json", "w", encoding="utf-8") as file: json.dump(data, file, ensure_ascii=False, indent=4) print("Дані збережено у JSON форматі")
Читання з JSON файлу
import json # Читання з JSON файлу with open("user_data.json", "r", encoding="utf-8") as file: data = json.load(file) print(f"Ім'я: {data['name']}") print(f"Вік: {data['age']}") print(f"Місто: {data['city']}") print(f"Хобі: {', '.join(data['hobbies'])}")
Робота зі списком об'єктів у JSON
import json # Список студентів students = [ {"name": "Іван", "grade": 95}, {"name": "Марія", "grade": 88}, {"name": "Олег", "grade": 92} ] # Збереження with open("students.json", "w", encoding="utf-8") as file: json.dump(students, file, ensure_ascii=False, indent=2) # Читання та обробка with open("students.json", "r", encoding="utf-8") as file: students = json.load(file) for student in students: print(f"{student['name']}: {student['grade']} балів")
Контекстний менеджер with
Чому важливо використовувати with
# Небезпечно (файл може не закритися при помилці): file = open("data.txt", "r") content = file.read() file.close() # Може не виконатися при помилці # Безпечно (файл завжди закриється): with open("data.txt", "r") as file: content = file.read() # Файл автоматично закритий тут
Робота з декількома файлами одночасно
# Копіювання вмісту з одного файлу в інший with open("source.txt", "r") as source, open("destination.txt", "w") as dest: for line in source: dest.write(line) print("Файл скопійовано!")
Вкладені контекстні менеджери
# Читання з одного файлу та запис в інший з перетворенням with open("input.txt", "r") as infile: with open("output.txt", "w") as outfile: for line in infile: outfile.write(line.upper())
Розширена обробка помилок
Обробка різних типів помилок
def safe_file_operation(filename): try: with open(filename, "r") as file: content = file.read() return content except FileNotFoundError: print(f"Помилка: Файл '{filename}' не існує") except PermissionError: print(f"Помилка: Немає прав доступу до файлу '{filename}'") except IOError as e: print(f"Помилка вводу-виводу: {e}") except Exception as e: print(f"Несподівана помилка: {e}") return None # Використання content = safe_file_operation("important.txt") if content: print(content)
Обробка з блоком else та finally
def process_file(filename): file = None try: file = open(filename, "r") data = file.read() print(f"Файл прочитано: {len(data)} символів") except FileNotFoundError: print("Файл не знайдено") except Exception as e: print(f"Помилка: {e}") else: print("Операція успішна!") finally: if file: file.close() print("Файл закрито") process_file("data.txt")
Корисні поради та найкращі практики
1. Завжди вказуйте кодування
# Добре with open("file.txt", "r", encoding="utf-8") as file: content = file.read()
2. Використовуйте pathlib для роботи зі шляхами
from pathlib import Path file_path = Path("data") / "subfolder" / "file.txt" if file_path.exists(): content = file_path.read_text(encoding="utf-8")
3. Обробляйте великі файли порціями
# Для великих файлів читайте по рядках with open("huge_file.txt", "r") as file: for line in file: # Ефективне використання пам'яті process_line(line) def process_line(line): # Обробка одного рядка print(line.strip())
4. Використовуйте try-except для безпечних операцій
try: with open("config.txt", "r") as file: config = file.read() except FileNotFoundError: # Створити файл з налаштуваннями за замовчуванням with open("config.txt", "w") as file: file.write("default_setting=true")
5. Не забувайте про відносні шляхи
import os # Отримати поточну директорію current_dir = os.getcwd() print(f"Поточна директорія: {current_dir}") # Побудувати шлях відносно поточної директорії file_path = os.path.join(current_dir, "data", "file.txt")