Работа с файловой системой

Материал из Институт биоинформатики
Перейти к: навигация, поиск

В этом разделе описаны основные средства работы с файлами и директориями в языке 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:

  • В ASCII число знаков текста будет эквивалентно числу байт, в других кодировках один знак будет эквивалентен одному, двум или более байтам https://habrahabr.ru/post/158639/