2010-03-16 7 views
1

Le corps de Net :: HTTPResponse est un objet semblable à un flux, et vous pouvez lire son entrée dans des mandrins paresseux en utilisant read_body. Dans le reste du rubis, les vapeurs sont représentées en tant que classe IO. Y at-il un wrapper ou quelque chose qui me permet d'utiliser un Net :: HTTPResponse comme s'il s'agissait d'un objet IO?Net :: HTTPResponse body as IO

+0

moi aussi. juste aujourd'hui j'ai un besoin de diffuser un HTTPResponse à un CVS :: Reader. Si je reçois quelque chose de fonctionnel, même si moche, je posterai une réponse. – Kevin

Répondre

3

Utilisez la bibliothèque OpenURI fournie avec Ruby standard. Il utilise Net :: Http sous le capot et fournit un objet semblable à un fichier.

require 'open-uri' 
open('http://example.com/some_file') do |f| 
    f.each_line do |line| 
    puts "http line: #{line}" 
    end 
do 
+2

Si la longueur du contenu est supérieure à une certaine taille, cela écrira d'abord sur le disque (Tempfile), puis donnera l'objet I/O Tempfile. Juste un FYI dans le cas où l'espace disque est une contrainte ou le désir était pour le streaming sans tampon sur le disque. – jbielick

0

Si vous êtes d'accord avec l'utilisation de threads (peut-être sûr que dans les IRM), je l'ai utilisé cela avec un certain succès:

# create an writable IO to write the response to 
# and a readable IO to return/yield to the caller 
read_io, write_io = IO.pipe 

write_io.binmode 
read_io.binmode 

# in a separate thread, continue adding chunks to the writable IO, 
# which is connected to the readable IO we return 
Thread.new do 
    begin 
    # pipe chunks to the write stream 
    # response is the Net::HTTPSuccess object 
    response.read_body { |chunk| write_io << chunk } 
    ensure 
    write_io.close 
    Thread.current.exit 
    end 
end 

# yield a readable stream while the thread feeds the writable 
yield read_io 

Nous créons une lecture IO et d'une écriture IO qui sont connecté avec IO.pipe. Puisque read_body est une opération de blocage qui cèdera au bloc que nous lui donnons jusqu'à ce que tout le corps soit terminé (contenu entier en mémoire), nous devons read_body dans un thread séparé. Lorsque des morceaux sont reçus, ils sont transmis à notre write_io. Le write_io est essentiellement un proxy, mais nous pouvons lire à partir du read_io de manière paresseuse sans attendre que tout le corps de la réponse soit téléchargé. Ceci est utile pour les parseurs de streaming et peut-être aussi votre cas d'utilisation. CSV accepte un IO et peut être analysé paresseusement avec cette méthode comme ceci:

CSV.new(io).to_enum 

qui vous donnerait un ENUM paresseux de lignes csv.