Recupero le immagini con open-uri da un sito Web remoto e le conservo sul mio server locale all'interno dell'applicazione Ruby on Rails. La maggior parte delle immagini sono state mostrate senza problemi, ma alcune immagini non si sono mostrate.Perché OpenURI considera i file con dimensioni inferiori a 10kb come StringIO?
Dopo un lunghissimo debug-sessione ho finalmente scoperto (grazie a this blogpost) che la ragione di questo è che il class Buffer
nei file open-uri-libary Tratta con meno di 10KB di dimensioni come IO-oggetti anziché ai file temporanei.
sono riuscito a aggirare questo problema seguendo la risposta da Micah Winkelspecht a this StackOverflow question, dove ho messo il seguente codice all'interno di un file nei miei inizializzatori:
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
Questo funziona come previsto finora, ma io continua a chiedersi, perché hanno messo questo codice nella libreria, in primo luogo? Qualcuno conosce un motivo specifico, , perché i file di dimensioni inferiori a 10 KB sono trattati come StringIO?
Poiché il codice sopra riportato praticamente resetta questo comportamento a livello globale per tutta la mia applicazione, voglio solo assicurarmi di non infrangere nient'altro.
grazie, bella spiegazione – klaffenboeck
Non proprio corretto. La stringa utilizzata come buffer in questo caso non ha una dimensione fissa; le stringhe in Ruby vengono ridimensionate dinamicamente. In effetti, è possibile ridimensionare i buffer in modo dinamico nella maggior parte delle lingue (anche se non sempre automaticamente). Sospetto che il vero motivo dell'uso di StringIO per i file di piccole dimensioni sia un compromesso tra prestazioni e memoria. – pelle
Vero @pelle. Notando che hai detto non abbastanza. Nel caso di BLOB, * qualsiasi * supposizione sull'adattamento potrebbe essere interrotta da un BLOB ancora più grande. Ciò include ciò che non si adatta alla memoria. A un certo punto, la gestione degli stream richiede lo streaming e la classe Buffer sceglie 10K come punto di svolta per abbandonare e gestire il file tramite lo streaming. –