Я извлекаю изображения с открытым uri с удаленного сайта и сохраняю их на своем локальном сервере в моем приложении Ruby on Rails. Большинство изображений были показаны без проблем, но некоторые изображения просто не отображались.Почему OpenURI обрабатывает файлы размером до 10 КБ в качестве StringIO?
После очень долгой отладки-сессии я, наконец, узнал (благодаря this blogpost), что причина этого заключается в том, что class Buffer
в open-uri-libary лечит файлы с менее чем 10kb размера, как IO-объектов вместо временных файлов.
мне удалось обойти эту проблему, после ответа от Михея Winkelspecht до this StackOverflow question, где я поставил следующий код в файл в моем инициализаторах:
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?
Поскольку приведенный выше код практически полностью сбрасывает это поведение в глобальном масштабе для всего моего приложения, я просто хочу убедиться, что я не нарушаю ничего другого.
спасибо, приятное объяснение – klaffenboeck
Не совсем правильно. Строка, которая используется в качестве буфера в этом случае, не имеет фиксированного размера; строки в Ruby динамически изменяются. Действительно, вы можете динамически изменять размер буферов на большинстве языков (хотя не всегда автоматически). Я подозреваю, что реальной причиной использования StringIO для небольших файлов является компромисс между производительностью и памятью. – pelle
True @pelle. Отмечая, что вы сказали не совсем. В случае BLOBs * любое * предположение об установке может быть разбито еще большим BLOB. Это включает в себя то, что не поместится в памяти. В какой-то момент обработка потоков требует потоковой передачи, а класс Buffer выбирает 10K в качестве точки опроса, чтобы просто сдаться и обработать файл потоком. –