Операции ввода-вывода файлов Python приводят к «[Errno 23] Слишком много открытых файлов в системе» - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь итеративно обработать список сжатых файлов. Каждый сжатый файл содержит большое количество документов XML, некоторые даже содержат до 92 000 документов XML. Внутри вложенного цикла я перебираю список извлеченных XML-документов и извлекаю конкретные значения полей XML из каждого XML-документа. Проблема в том, что я продолжаю сталкиваться с следующей проблемой после 5 минут работы скрипта: [Errno 23] Слишком много открытых файлов в системе .

Когда я раскомментирую вызов 100 parse_xml_files ’из основной функции, приведенной ниже, сценарий завершается без проблем. Я запутался, что вызывает эту проблему, так как файлы читаются с помощью диспетчера контекста, который должен сам закрыть все файлы XML после их обработки. Может быть, я что-то упускаю.

Похоже, что многие решения для работы с stackoverflow вращаются вокруг постоянного увеличения лимита количества открытых файлов с помощью «ulimit -a». Однако это решение не работает для меня, так как я имею дело с большим количеством файлов.

Любое понимание этого очень ценится!

from os import system
from os import walk, path as ospath, makedirs
from bs4 import BeautifulSoup
from os import walk


def find_all_xml_files(path):
    file_queue = []
    for (dirpath, _, filenames) in walk(path):
        if len(filenames) == 0:
            continue
        for filename in filenames:
            if filename.endswith('.xml'):
                file_queue.append(f'{dirpath}/{filename}')
            else:
                # Ignore unknown file formats
                pass 
    return file_queue


def parse_xml_files(xml_files):
    for xml_file in xml_files:
        with open(xml_file, 'r') as f:
            handler = f.read()
        xml_doc = BeautifulSoup(handler, 'lxml')
        """ And then extract and store various parts of the XML document """


def main():
    # Retrieve list of files to process
    compressed_files = get_files_to_process()

    for compressed_file in compressed_files:
         temp_folder = f'.temp'  # Temporary directory to store extracted contents

         # Create temporary storage file
         makedirs(temp_folder)

         # Unzip the compressed file
         unzip_cmd = f'unzip -o {compressed_file} -d {temp_folder}'
         system(unzip_cmd)

         # Retrieve list of extracted XML files for parsing
         xml_files = find_all_xml_files(temp_folder)
         parse_xml_files(xml_files)  # Commenting this line helps the script go to completion without any errors

         # Delete temporary direcory and its content
         delete_cmd = f'rm -r {temp_folder}'
         system(delete_cmd)

main()

Обновление

Это трассировка:

Traceback (most recent call last):
  File "main.py", line 36, in <module>
  File "main.py", line 30, in main
  File "main.py", line 8, in main
  OSError: [Errno 23] Too many open files in system: '.temp/xyz.xml'

После показа вышеупомянутой трассировки мне приходится перезагружать всю систему, потому что все, что работает на моем ноутбуке, перестает отвечать.

...