Я вызываю exiftool для извлечения тегов XMP, таких как Description, из больших видео размером 5 ГБ и более. Мое приложение - Python, и я видел некоторые файлы, которые истощают память; Я вызываю это так:
fp = open('9502_UAS_2.mov', 'rb')
CMD = 'exiftool -api largefilesupport=1 -sort -a -S -G -struct -j -'
exiftool = subprocess.Popen(CMD.split(),
stdin=fp,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(json_bytes, stderr) = exiftool.communicate()
Чтобы изолировать проблему, я пробовал варианты в интерфейсе командной строки. Это показывает, что чтение из файла на диске происходит быстро и использует мало ОЗУ, тогда как чтение из STDIN (воссоздание указателя файла, прочитанного выше) очень медленное и использует много ОЗУ (я удалил выходные метаданные JSON ниже для ясность):
time exiftool -api largefilesupport=1 -sort -a -S -G -struct -j 9502_UAS.mov
real 0m0.196s
time cat 9502_UAS.mov | exiftool -api largefilesupport=1 -sort -a -S -G -struct -j -
real 0m33.514s
'top' показал, что второй потребляет до 1,4 ГБ ОЗУ для этого видеофайла 5,1 ГБ.
Я хотел бы понять, почему чтение из STDIN происходит медленно и потребляет так много памяти, поэтому я могу следить за такими ограничениями, как нехватка памяти на моих серверах. Считывает ли exiftool последовательно весь поток STDIN буферизацию файла до тех пор, пока он не получит двоичную информацию, необходимую для анализа метаданных? Разве это не seek () - назад и вперед, чтобы найти то, что ему нужно?
И наоборот, почему он так быстро запускается с файлом на собственном диске? Использует ли exiftool файловую систему с отображением памяти для быстрого перехода к разделам файла, которые необходимо проанализировать?
В идеале я бы читал из STDIN, потому что реальным источником файла приложения является ведро AWS S3, и я не хочу копировать файл на локальный диск AWS EC2, если я могу этого избежать, поэтому любые подсказки, чтобы сделать чтение stdin эффективным, могли бы помочь .
Спасибо.