Работа с файловой системой
В этом разделе описаны основные средства работы с файлами и директориями в языке Python.
Содержание
Встроенные функции
Открытие файла
Чтобы произвести какую-либо операцию с файлом, сперва его нужно открыть. Для этого существует функция open().
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
Функция может принимать много аргументов, но в большинстве случаев имеют значение только первые два: путь к файлу (абсолютный или относительно рабочей директории) и режим, в котором вы хотите открыть файл. Открытие текстового файла для чтения обычно выглядит так:
f = open("yourfile.txt", "r")
При этом в переменную f сохраняется объект типа file object (файловый объект).
Очень важно правильно выбрать режим доступа к файлу, иначе можно потерять все хранящиеся в файле данные, ну или просто исполнение кода прервется из-за исключений.
Список режимов доступа к файлу
Аргумент mode может принимать следующие значения (таблица отсюда с изменениями):
Режимы доступа к файлу | |
---|---|
r | Открывает файл только для чтения. Режим по умолчанию. |
rb | Открывает файл для чтения в двоичном формате. |
r+ | Открывает файл для чтения и добавления информации в конец файла. |
rb+ | Открывает файл для чтения и добавления информации в конец файла в двоичном формате. |
w | Открывает файл только для записи. Если файл уже существует, стирает его содержимое при открытии. Создает файл, если такового не существует. |
wb | Открывает файл для записи в двоичном формате. Если файл уже существует, стирает его содержимое при открытии. Создает файл, если такового не существует. |
w+ | Открывает файл для чтения и записи. Если файл уже существует, стирает его содержимое при открытии. Создает файл, если такового не существует. |
wb+ | Открывает файл для чтения и записи в двоичном формате. Если файл уже существует, стирает его содержимое при открытии. Создает файл, если такового не существует. |
a | Открывает файл для добавления информации в конец файла. Создает файл, если такового не существует. |
ab | Открывает файл для добавления информации в конец файла в двоичном формате. Создает файл, если такового не существует. |
a+ | Открывает файл для добавления информации в конец файла и чтения. Создает файл, если такового не существует. |
ab+ | Открывает файл для добавления информации в конец файла и чтения в двоичном формате. Создает файл, если такового не существует. |
Если при попытке открыть файл возникает ошибка UnicodeError, это значит, что кодировка файла отличается от кодировки по умолчанию (которая зависит от платформы). В таком случае функции open()
следует передать кодировку открываемого файла, например, UTF8:
f = open("yourfile.txt", "r", encoding="utf8")
Закрытие файла
После открытия файла и работы с ним важно не забыть его закрыть, используя метод файлового объекта close()
. При этом файл становится недоступен для чтения и записи.
f = open("yourfile.txt", "w") # операции с файлом f.close()
Часто бывает удобнее другая форма записи, при которой файл закрывается автоматически, когда интерпретатор выходит из блока with
:
with open("yourfile.txt", "w") as f: # операции с открытым файлом # и еще операции с открытым файлом # а здесь файл уже закрыт
Чтение содержимого файла
Считать содержимое файла из файлового объекта можно по-разному. В качестве примера возьмем файл example.txt со следующим текстом внутри:
вороне раз кусок лисицы послал какой-то добрый бог и басня стала и короче и справедливее в разы
Самый простой способ считать информацию из файла - воспользоваться методом файлового объекта read()
. Он возвращает все содержимое файла в виде одной строки.
with open("example.txt", "r") as f: text = f.read() print(text) вороне раз кусок лисицы послал какой-то добрый бог и басня стала и короче и справедливее в разы
Если если применить к тому же файловому объекту read()
во второй раз, то он вернет пустую строку. Это происходит потому, что после первого прочтения указатель (stream position) сдвинулся в конец файла и при втором прочтении пытается продолжить чтение с конца.
Методу read()
можно явно задавать, сколько байт считать. Тогда указатель будет сдвигаться на определенное количество знаков и с этой позиции продолжит чтение при повторном вызове:
[1]
with open("example.txt", "r") as f: print("Первое считывание:", f.read(13)) print("Второе считывание:", f.read(10)) Первое считывание: вороне раз ку Второе считывание: сок лисицы
Метод tell()
позволяет узнать, в каком месте (в скольки байтах от начала файла) находится указатель в данный момент. Переместить указатель в определенную позицию можно с помощью seek()
, причем можно в качестве второго аргумента передать положение, относительно которого нужно смещаться: 0 - от начала файла, 1 - от текущей позиции, 2 - от конца файла.
with open("example.txt", "r") as f: f.seek(30) print(f.tell()) # 30 f.seek(4, 0) # смещаемся на 4 байта от начала текста print(f.tell()) # 4
Построчное считывание
Часто гораздо удобнее читать информацию из файла не единым массивом, а построчно. Это упрощает дальнейшую обработку данных, а если в файле содержится миллион длинных строк, то помогает избежать переполнения оперативной памяти компьютера. Следует помнить, что при этом в возвращаемых строках сохраняются невидимые знаки окончания строки "\n".
Можно просто итерироваться по строкам файлового объекта:
with open("example.txt", "r") as f: for line in f: print(line, end='') вороне раз кусок лисицы послал какой-то добрый бог и басня стала и короче и справедливее в разы
Другой способ - readlines()
. Этот метод возвращает список, содержащий все строки файла:
with open("example.txt", "r") as f: print(f.readlines()) ['вороне раз кусок лисицы\n', 'послал какой-то добрый бог\n', 'и басня стала и короче\n', 'и справедливее в разы\n']
Считать одну строку можно при помощи readline()
, при этом указатель смещается к началу следующей строки:
with open("example.txt", "r") as f: print("Первая строка:", f.readline()) print("Вторая строка:", f.readline()) Первая строка: вороне раз кусок лисицы Вторая строка: послал какой-то добрый бог
Запись в файл
Для записи в файл существует метод write()
, который в качестве аргумента принимает только строку.
Важно не забывать указывать соответствующий режим открытия файла: "w" для перезаписи содержимого, "a" для дозаписи в конец.
with open("example.txt", "w") as out: out.write("New, what do you own the world?\nHow do you own disorder, disorder") # Содержимое файла стирается, в него записывается эта строка
Чтобы записать в файл данные, хранящиеся в списке, их необходимо преобразовать в строку. Например, так:
text = ["aerials, in the sky\n", "when you lose small mind\n", "you free your life\n"] with open("example.txt", "w") as out: out.write("".join(text))
То же самое можно сделать при помощи метода writelines()
:
text = ["aerials, in the sky\n", "when you lose small mind\n", "you free your life\n"] with open("example.txt", "w") as out: out.writelines(text)
Объекты типа int (целые числа) или bool (числа с плавающей точкой) для записи в файл следует превратить в строку при помощи функции str()
.
Средства модуля os
Модуль os содержит множество инструментов для работы с операционной системой. В данном разделе рассматриваются только функции, имеющие отношение к работе с файлами и директориями.
Чтобы использовать функции модуля, необходимо сначала его импортировать: import os
-
os.listdir(path=".")
- возвращает список всех файлов и субдиректорий в выбранной директории (по умолчанию - в текущей). -
os.getcwd()
- возвращает строку с адресом текущей рабочей директории. -
os.chdir(path)
- изменяет рабочую директорию на указанную. -
os.mkdir(path)
- создает указанную директорию. -
os.walk(top, topdown=True)
- для указанной директории и каждой ее субдиректории возвращает кортеж из пути до директории, списка субдиректорий и списка файлов в данной директории. По умолчанию функция движется по каталогам сверху вниз, с аргументом topdown=False движется снизу вверх. Например, запустим функцию в текущей директории, в которой есть три файла и одна субдиректория с одним файлом:
import os for i in os.walk("."): print(i) ('.', ['mydir'], ['alignment.fna', 'text.txt', 'Kookaburra.mp3']) ('./mydir', [], ['NewFile2.txt'])
Вложенный модуль os.path
Модуль os.path содержит ряд функций для работы с путями. Ниже представлена лишь часть их.
-
os.path.exists(path)
- позволяет проверить, существует ли указанный путь. Возвращает True или False. -
os.path.isfile(path)
- позволяет проверить, является ли указанный путь файлом. Возвращает True или False. -
os.path.isdir(path)
- позволяет проверить, является ли указанный путь директорией. Возвращает True или False. -
os.path.split(path)
- возвращает кортеж из двух элементов: первый - весь указанный путь до последнего "/" включительно, второй - последний компонент указанного пути (после последнего "/"). Помогает разделить название директории или файла и путь до него.
средства модуля shutil
Модуль shutil дает возможность копировать файлы и целые директории. Наиболее используемые функции:
-
shutil.copyfile(src, dst)
- копирует содержимое файла по указанному пути (аргумент src) и создает новый файл с таким же содержимым по второму пути (dst). При этом права доступа к файлу не копируются. Если указанный в dst файл уже существует, он будет перезаписан. -
shutil.copy(src, dst)
- делает то же самое, но копирует файл вместе с правами доступа. -
shutil.copytree(src, dst)
- копирует директорию вместе со всем ее содержимым. Если путь dst уже существует, возникнет ошибка. -
shutil.move(src, dst)
- перемещает файл или директорию: создает копию по пути dst, исходный удаляет.
Ссылки
Ряд руководств по работе с файлами в Python:
- Презентация Константина Зайцева, преподавателя курса Python в Институте Биоинформатики https://drive.google.com/file/d/0B4n0ix5Fz3c-NE5tcFU0eC1NVVk/view
- Статья об основных методах работы с файловой системой от IBM https://www.ibm.com/developerworks/ru/library/l-python_part_8/
- Статья о встроенных функциях http://pythonicway.com/python-fileio
- Презентация о строках, кодировках, байтах и файлах от сотрудника JetBrains Сергея Лебедева https://compscicenter.ru/media/slides/python_2014_autumn/2014_10_08_python_2014_autumn.pdf
- Статья о вводе, выводе и записи в файл http://pep8.ru/doc/tutorial-2.6/8.html
- Статья о модуле os.path http://pythonworld.ru/moduli/modul-os-path.html
- Статья о модуле os http://pythonworld.ru/moduli/modul-os.html
- Статья о копировании файлов и директорий http://python-3.ru/page/kopirovanie-fajlov-v-python