При чтении потока из списка файлов можно управлять тем, как файлы открываются, предоставляя хук открытия через аргумент openhook
для функции fileinput.input()
или класса fileinput.FileInput()
.
Хук должен быть функцией, которая принимает два аргумента, имя файла filename
и режим mode
, и возвращает соответственно открытый файловый объект.
Модуль fileinput
предусматривает два полезных хука.
fileinput.hook_compressed(filename, mode)
:Функция fileinput.hook_compressed()
прозрачно открывает файлы, сжатые с помощью gzip
и bzip2
, распознаваемые c расширениями .gz
и .bz2
с помощью модулей gzip
и bz2
.
Такое поведение удобно использовать при анализе логов, которые подвергаются ротации с упаковкой в архив .tar.gz
или .tar.bz2
Если файлы не имеют расширения .gz
или .bz2
, то файл открывается нормально, т. е. с использованием встроенной функции open()
без какой-либо распаковки.
import fileinput, os # каталог логов path = '/path/to/log' # формируем список логов file_name = os.listdir(path) list_files = [] for file in file_names: list_files.append(os.path.join(path, file)) if list_files: with fileinput.FileInput(files=list_files, \ openhook=fileinput.hook_compressed) as fp: for line in fp: print(fp.filename(), line)
fileinput.hook_encoded(encoding, errors=None)
:Функция fileinput.hook_encoded()
открывает каждый файл с помощью функции open()
, используя заданную кодировку encoding
и обработчик ошибок errors
для чтения файла.
import fileinput, os # каталог файлов path = '/path/to/files' # формируем список file_name = os.listdir(path) list_files = [] for file in file_names: list_files.append(os.path.join(path, file)) if list_files: with fileinput.FileInput(files=list_files, \ openhook=fileinput.hook_encoded('utf-8', 'surrogateescape')) as fp: for line in fp: print(fp.filename(), line)