Я пытаюсь загрузить и распаковать набор файлов с удаленного сервера Apache. Я предоставляю список файлов .tbz (tar.bz2) для загрузки и распаковки на лету. Цель состоит в том, чтобы передать их с удаленного сервера Apache через распаковщик tar и немедленно направить их в мое хранилище Amazon AWS S3. Я делаю это, потому что файлы могут быть размером до 30 ГБ.
Я использую библиотеку python "smart_open", чтобы абстрагироваться от управления https и s3.
Код, который я здесь предоставил, прекрасно работает для небольших файлов. Как только я пытаюсь сделать это с большим файлом (более 8 МБ), я получаю следующую ошибку:
"EOFError: End of stream already reached"
Вот трассировка:
Traceback (most recent call last):
File "./script.py", line 28, in <module>
download_file(fileName)
File "./script.py", line 21, in download_file
for line in tfext:
File "/.../lib/python3.7/tarfile.py", line 706, in readinto
buf = self.read(len(b))
File "/.../lib/python3.7/tarfile.py", line 695, in read
b = self.fileobj.read(length)
File "/.../lib/python3.7/tarfile.py", line 537, in read
buf = self._read(size)
File "/.../lib/python3.7/tarfile.py", line 554, in _read
buf = self.cmp.decompress(buf)
EOFError: End of stream already reached
Когда я распечатываю строки, которые пишу в поток, я вижу, что я все еще прохожу первую часть файла до того, как выдается ошибка.
Что я пробовал до сих пор:
Я попытался указать одинаковый размер буфера для open () и tarfile.open (), но безуспешно.
Я также пытался ввести некоторую задержку между написанием каждой строки, но безрезультатно.
from smart_open import open
import tarfile
baseUrl = 'https://someurlpath/'
filesToDownload = ['name_of_file_to_download']
def download_file(fileName):
fileUrl = baseUrl + fileName + '.tbz'
with open(fileUrl, 'rb') as fin:
with tarfile.open(fileobj=fin, mode='r|bz2') as tf:
destination = 's3://some_aws_path/' + fileName + '.csv'
with open(destination, 'wb') as fout:
with tf.extractfile(tf.next()) as tfext:
for line in tfext:
fout.write(line)
for fileName in filesToDownload:
download_file(fileName)
Я хочу иметь возможность обрабатывать большие файлы точно так же, как я могу обрабатывать маленькие.