Подтвердить что ты не робот

Почему OpenURI обрабатывает файлы размером менее 10 КБ как StringIO?

Я извлекаю изображения с открытым uri с удаленного сайта и сохраняю их на своем локальном сервере в моем приложении Ruby on Rails. Большинство изображений были показаны без проблем, но некоторые изображения просто не отображались.

После очень долгого отладочного сеанса я наконец узнал (спасибо этот блогпост), что причина этого в том, что class Buffer в open-uri-libary обрабатывает файлы размером менее 10 КБ в качестве IO-объектов вместо tempfiles.

Мне удалось обойти эту проблему, выполнив ответ от Micah Winkelspecht на qaru.site/info/212624/..., где я поместил следующий код внутри файла в мои инициализаторы:

require 'open-uri'
# Don't allow downloaded files to be created as StringIO. Force a tempfile to be created.
OpenURI::Buffer.send :remove_const, 'StringMax' if OpenURI::Buffer.const_defined?('StringMax')
OpenURI::Buffer.const_set 'StringMax', 0

Это работает так, как ожидалось, но я все время задаюсь вопросом, почему они ввели этот код в библиотеку в первую очередь? Кто-нибудь знает определенную причину, почему файлы размером менее 10 КБ рассматриваются как StringIO?

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

4b9b3361

Ответ 1

Когда вы выполняете сетевое программирование, вы выделяете буфер с достаточно большим размером и отправляете и читаете единицы данных, которые будут помещаться в буфер. Однако при работе с файлами (или иногда вещами, называемыми BLOB) вы не можете предположить, что данные будут вписываться в ваш буфер. Итак, вам нужна специальная обработка для этих больших потоков данных.

(Иногда единицы данных, которые вписываются в буфер, называются пакетами. Однако пакеты действительно представляют собой уровень 4, например, кадры находятся на уровне 2. Поскольку это происходит с уровнем 7, их лучше назвать сообщениями. )

Для ответов, больших 10K, библиотека open-uri настраивает дополнительные служебные данные для записи в объекты потока. Когда в размере StringMax он просто содержит строку в сообщении, поскольку он знает, что он может поместиться в буфер.