Ciao a tutti,
avrei bosigno di porvi un quesito.
Ho creato un programmino con Qt-ruby che fa la copia in locale di alcuni
file presenti su un server remoto.
La richiesta HTTP la faccio così:
resp=Net::HTTP.get(URI.parse('http://' + url + ':' + port + path))
dove url, port e path sono variabili settate in precedenza.
Una volta effettuati tutti i controlli sulla presenza o meno della
cartella di destinazione, eseguo la scrittura del file.
fileExport = File.new(dir + "/CVIn" + @countDir.to_s + "/" +
nameFile,"wb")
fileExport.write(resp)
fileExport.close
Però succede che mentre sta cercando di eseguire la get mi dà questo
genere di errore:
c:/ruby/lib/ruby/1.8/net/protocol.rb:84:in `<<': failed to allocate
memory (NoMe
moryError)
from c:/ruby/lib/ruby/1.8/net/protocol.rb:84:in `read'
from c:/ruby/lib/ruby/1.8/net/http.rb:2209:in `read_body_0'
from c:/ruby/lib/ruby/1.8/net/http.rb:2170:in `read_body'
from c:/ruby/lib/ruby/1.8/net/http.rb:2195:in `body'
from c:/ruby/lib/ruby/1.8/net/http.rb:2134:in `reading_body'
from c:/ruby/lib/ruby/1.8/net/http.rb:1049:in `request'
from c:/ruby/lib/ruby/1.8/net/http.rb:945:in `request_get'
from c:/ruby/lib/ruby/1.8/net/http.rb:380:in `get_response'
... 8 levels...
from c:/ruby/lib/ruby/site_ruby/1.8/Qt/qtruby4.rb:241:in
`qt_metacall'
from c:/ruby/lib/ruby/site_ruby/1.8/Qt/qtruby4.rb:241:in
`method_missing
'
from c:/ruby/lib/ruby/site_ruby/1.8/Qt/qtruby4.rb:241:in `exec'
from Export_main.rb:35
Io credo che l'errore sia legato al fatto che cerca di portare tutto in
RAM.
Qualcuno sa dirmi di più?
Qualcuno sa indicarmi un'alternativa?
Spero che la mia richiesta non resti inascoltata...
Grazie mille a tutti, anticipatamente
Catiana
on 21.07.2008 11:47
on 21.07.2008 12:45
Catiana Trisolini wrote: > Ciao a tutti, > avrei bosigno di porvi un quesito. > > Ho creato un programmino con Qt-ruby che fa la copia in locale di alcuni > file presenti su un server remoto. > > La richiesta HTTP la faccio così: > > resp=Net::HTTP.get(URI.parse('http://' + url + ':' + port + path)) > > dove url, port e path sono variabili settate in precedenza. > > Una volta effettuati tutti i controlli sulla presenza o meno della > cartella di destinazione, eseguo la scrittura del file. > > fileExport = File.new(dir + "/CVIn" + @countDir.to_s + "/" + > nameFile,"wb") > fileExport.write(resp) > fileExport.close > > Però succede che mentre sta cercando di eseguire la get mi dà questo > genere di errore: > > c:/ruby/lib/ruby/1.8/net/protocol.rb:84:in `<<': failed to allocate > memory (NoMe > moryError) > from c:/ruby/lib/ruby/1.8/net/protocol.rb:84:in `read' > from c:/ruby/lib/ruby/1.8/net/http.rb:2209:in `read_body_0' > from c:/ruby/lib/ruby/1.8/net/http.rb:2170:in `read_body' > from c:/ruby/lib/ruby/1.8/net/http.rb:2195:in `body' > from c:/ruby/lib/ruby/1.8/net/http.rb:2134:in `reading_body' > from c:/ruby/lib/ruby/1.8/net/http.rb:1049:in `request' > from c:/ruby/lib/ruby/1.8/net/http.rb:945:in `request_get' > from c:/ruby/lib/ruby/1.8/net/http.rb:380:in `get_response' > ... 8 levels... > from c:/ruby/lib/ruby/site_ruby/1.8/Qt/qtruby4.rb:241:in > `qt_metacall' > from c:/ruby/lib/ruby/site_ruby/1.8/Qt/qtruby4.rb:241:in > `method_missing > ' > from c:/ruby/lib/ruby/site_ruby/1.8/Qt/qtruby4.rb:241:in `exec' > from Export_main.rb:35 > > Io credo che l'errore sia legato al fatto che cerca di portare tutto in > RAM. > > Qualcuno sa dirmi di più? > Qualcuno sa indicarmi un'alternativa? > Spero che la mia richiesta non resti inascoltata... > > Grazie mille a tutti, anticipatamente > > Catiana Potresti anche fare un socket che legge piano piano il contenuto. Ad esempio: path = "/"#Il percorso del documento sul server nomefile = "result.txt" #Il nome del file in locale server = "www.x.com" #Il nome del server (senza http:// nè il resto del percorso) port = 80 #La porta del server File.open(nomefile,"wb") {|f|} #Crea il file vuoto sock = TCPSocket.new(server,port) #Si collega al server sock.puts "GET #{path} HTTP/1.1\r\n" #Esegue una richiesta di tipo GET. while select([sock],[],[],1.5)[0][0] == sock #Verifica che il socket sia pronto e che il file non sia finito export = File.open(nomefile, "a+") {|file| #Riapre il file in modalità Append file.write sock.recv(1024) #Scrive 1KB appena letto dal socket } #Chiude il file end Prova se funziona, in teoria non dovrebbe dare più errori come NoMemoryError (prendendo solo 1KB alla volta). Poi in base alla grandezza della ram e del file, puoi modificare il "1024" in recv.
on 21.07.2008 14:57
> Potresti anche fare un socket che legge piano piano il contenuto. Ad > esempio: > > path = "/"#Il percorso del documento sul server > nomefile = "result.txt" #Il nome del file in locale > server = "www.x.com" #Il nome del server (senza http:// nè il resto del > percorso) > port = 80 #La porta del server > > File.open(nomefile,"wb") {|f|} #Crea il file vuoto > sock = TCPSocket.new(server,port) #Si collega al server > sock.puts "GET #{path} HTTP/1.1\r\n" #Esegue una richiesta di tipo GET. > while select([sock],[],[],1.5)[0][0] == sock #Verifica che il socket sia > pronto e che il file non sia finito > export = File.open(nomefile, "a+") {|file| #Riapre il file in modalità > Append > file.write sock.recv(1024) #Scrive 1KB appena letto dal socket > } #Chiude il file > end > > Prova se funziona, in teoria non dovrebbe dare più errori come > NoMemoryError (prendendo solo 1KB alla volta). Poi in base alla > grandezza della ram e del file, puoi modificare il "1024" in recv. Ciao Simone, prima di tutto grazie per aver risposto. Mi dà però un'altro genere di errore: undefined method `[]' for nil:NilClass credo che il punto in cui si fermi sia questo: while select([sock],[],[],1.5)[0][0] == sock Grazie tante. Catiana
on 21.07.2008 16:04
Catiana Trisolini wrote: >> Potresti anche fare un socket che legge piano piano il contenuto. Ad >> esempio: >> >> path = "/"#Il percorso del documento sul server >> nomefile = "result.txt" #Il nome del file in locale >> server = "www.x.com" #Il nome del server (senza http:// nè il resto del >> percorso) >> port = 80 #La porta del server >> >> File.open(nomefile,"wb") {|f|} #Crea il file vuoto >> sock = TCPSocket.new(server,port) #Si collega al server >> sock.puts "GET #{path} HTTP/1.1\r\n" #Esegue una richiesta di tipo GET. >> while select([sock],[],[],1.5)[0][0] == sock #Verifica che il socket sia >> pronto e che il file non sia finito >> export = File.open(nomefile, "a+") {|file| #Riapre il file in modalità >> Append >> file.write sock.recv(1024) #Scrive 1KB appena letto dal socket >> } #Chiude il file >> end >> >> Prova se funziona, in teoria non dovrebbe dare più errori come >> NoMemoryError (prendendo solo 1KB alla volta). Poi in base alla >> grandezza della ram e del file, puoi modificare il "1024" in recv. > > > Ciao Simone, > prima di tutto grazie per aver risposto. > > Mi dà però un'altro genere di errore: > > undefined method `[]' for nil:NilClass > > credo che il punto in cui si fermi sia questo: > while select([sock],[],[],1.5)[0][0] == sock > > Grazie tante. > Catiana Vero, hai ragione. Infatti select ritorna "nil" se non va a buon fine. Quindi bisogna farlo separatamente: risultato = true while risultato ... (tutto quello di prima) risultato = select([sock],[],[],1.5) risultato = (risultato[0][0] == sock) if risultato != nil end Prova ora, spero che non dia altri errori.
on 21.07.2008 16:48
> > Vero, hai ragione. Infatti select ritorna "nil" se non va a buon fine. > Quindi bisogna farlo separatamente: > > risultato = true > while risultato > ... (tutto quello di prima) > risultato = select([sock],[],[],1.5) > risultato = (risultato[0][0] == sock) if risultato != nil > end > > Prova ora, spero che non dia altri errori. Ciao Simone, credo ci sia ancora qualcosa che non va. Mi spiego: il codice, correggimi se sbaglio dovrebbe essere così: path = @pathChildrennomefile = @em_mw.cmbDirectory.currentText + "/CVIn" + @countDir.to_s + "/" + nameFile server = "10.0.0.1" port = 9200 File.open(nomefile,"wb") {|f|} #Crea il file vuoto risultato = true sock = TCPSocket.new(server,port) #Si collega al server sock.puts "GET #{path} HTTP/1.1\r\n" #Esegue una richiesta di tipo GET while risultato export = File.open(nomefile, "a+") {|file| file.write(sock.recv(1024)) } #Chiude il file risultato = select([sock],[],[],1.5) risultato = (risultato[0][0] == sock) if risultato != nil end Ora se provo a stampare a video sock.puts "GET #{path} HTTP/1.1\r\n ciò che ho è nil; infatti il programmino sembra bloccarsi ma non genera errori. Grazie mille per la tua disponibilità, davvero. Catiana
on 22.07.2008 00:09
> Ciao Simone, > credo ci sia ancora qualcosa che non va. > Mi spiego: > > il codice, correggimi se sbaglio dovrebbe essere così: > > path = @pathChildrennomefile = @em_mw.cmbDirectory.currentText + "/CVIn" > + > @countDir.to_s + "/" + > nameFile > server = "10.0.0.1" > port = 9200 > File.open(nomefile,"wb") {|f|} #Crea il file vuoto > risultato = true > sock = TCPSocket.new(server,port) #Si collega al server > sock.puts "GET #{path} HTTP/1.1\r\n" #Esegue una richiesta di tipo GET > while risultato > export = File.open(nomefile, "a+") {|file| > file.write(sock.recv(1024)) > } #Chiude il file > risultato = select([sock],[],[],1.5) > risultato = (risultato[0][0] == sock) if risultato != nil > end > > Ora se provo a stampare a video sock.puts "GET #{path} HTTP/1.1\r\n > ciò che ho è nil; infatti il programmino sembra bloccarsi ma non genera > errori. > > Grazie mille per la tua disponibilità, davvero. > > Catiana Sì, effettivamente ora che lo provo vedo che non funziona. Era sbagliata la richesta GET. Ecco la versione testata. Ancora ci dovrò lavorare un po', perché (provando con un file exe) non fa proprio un lavoro eccellente, però se si tratta di scaricare qualcosa di meno "preciso", va bene. path = "/"#Il percorso del documento sul server nomefile = "result.txt" #Il nome del file in locale server = "www.google.it" #Il nome del server (senza http:// nè il resto del percorso) port = 80 #La porta del server File.open(nomefile,"wb") {|f|} #Crea il file vuoto sock = TCPSocket.new(server,port) #Si collega al server sock.puts "GET #{path} HTTP/1.1\r\nHost: #{server}\r\n\r\n" #Esegue una richiesta di tipo GET. sock.recv(1024) #Riceve gli header non necessari times = 0 #Serve a eliminare dal file la grandezza in byte dei dati che il server invia loop do written = "" export = File.open(nomefile, "a+") {|file| #Riapre il file in modalità Append written=sock.recv(1024) #Scrive 1KB appena letto dal socket (senza scrivere gli header) if times == 0 spltn = written.split("\r\n") file.write spltn[1,spltn.size-1].join("\r\n") else file.write written end } #Chiude il file if written.delete("\r\n") == "" or written.delete("\r\n") == "0" break end times += 1 end
on 22.07.2008 12:53
> path = "/"#Il percorso del documento sul server > nomefile = "result.txt" #Il nome del file in locale > server = "www.google.it" #Il nome del server (senza http:// nè il resto > del percorso) > port = 80 #La porta del server > > File.open(nomefile,"wb") {|f|} #Crea il file vuoto > sock = TCPSocket.new(server,port) #Si collega al server > sock.puts "GET #{path} HTTP/1.1\r\nHost: #{server}\r\n\r\n" #Esegue una > richiesta di tipo GET. > sock.recv(1024) #Riceve gli header non necessari > times = 0 #Serve a eliminare dal file la grandezza in byte dei dati che > il server invia > loop do > written = "" > export = File.open(nomefile, "a+") {|file| #Riapre il file in modalità > Append > written=sock.recv(1024) #Scrive 1KB appena letto dal socket (senza > scrivere gli header) > if times == 0 > spltn = written.split("\r\n") > file.write spltn[1,spltn.size-1].join("\r\n") > else > file.write written > end > } #Chiude il file > if written.delete("\r\n") == "" or written.delete("\r\n") == "0" > break > end > times += 1 > end Grazie mille Simone, ora funziona. Non so davvero come ringraziarti!! Sei stato gentilissimo. Grazie ancora. Catiana