2013-04-18 10 views
17

Ich muss Code schreiben, der feststellen wird, ob eine Datei vorhanden ist, indem Sie ihre URL überprüfen.Wie überprüfe ich, ob eine Datei existiert, die ihre URL verwendet, ohne sie herunterzuladen?

ich implementieren Derzeit dies:

error_code = 400; 
response = Net::HTTP.get_response(URI(url)); 
return response.code.to_i < error_code; 

Aber, es ist nicht richtig funktioniert, weil jedes Mal, wenn Sie die Datei herunterlädt, die wirklich langsam ist, wenn ich große Dateien oder viele von ihnen haben.

Wie kann ich feststellen, ob eine Datei auf der Remote-Seite existiert, ohne sie herunterzuladen?

+0

Haben Sie Zugriff auf den serverseitigen Code? Können Sie die Controller ändern? – shishirmk

+5

Beenden Sie Ihre Zeilen nicht mit ';'. Dies ist nicht C oder Perl. –

+0

Siehe [HTTP-Verben] (http://en.wikipedia.org/wiki/HTTP_Verbs#Request_methods), speziell die 'HEAD'-Methode. Wenn du die Verben besser kennst, findest du es einfacher, einen Weg zu finden, solche Sachen zu machen, unabhängig von der Bibliothek. – iain

Antwort

28

Wenn Sie Net verwenden möchten :: HTTP, dann können Sie es auf diese Weise tun:

uri = URI(url) 

request = Net::HTTP.new uri.host 
response= request.request_head uri.path 
return response.code.to_i == 200 
+2

Erwähnenswert ist, dass 'Net :: HTTP' in der Stand-Ruby-Spezifikation enthalten ist. – bdares

+0

beachten Sie andere gültige Antwortcodes, wie 301 zum Beispiel, die Datei kann tatsächlich da sein, in der nächsten URL von der ersten Anfrage abgerufen werden. Beispiel: tinyurl – fabriciofreitag

4

Sie so etwas wie dieses

require "rest-client" 

begin 
    exists = RestClient.head("http://google.com").code == 200 
rescue RestClient::Exception => error 
    exists = (error.http_code != 404) 
end 

Dann „existiert“ ein logischer Wert ist abhängig, ob ob es existiert oder nicht. Dies wird nur die Header-Informationen, nicht die Datei, so dass es für kleine oder große Dateien identisch sein sollte.

+0

Das ist gut, aber ich möchte nicht zusätzliche verwenden Edelsteine ​​oder libs dafür – Ph0en1x

+0

Verstanden, ich bin mir nicht sicher einer Möglichkeit, es zu tun, ohne etwas wie Rest-Client zu verwenden. Viel Glück! – JoshEmory

2

Ich würde es auf diese Weise schreiben:

require 'net/http' 

ERROR_CODE = 400 

response = Net::HTTP.start('www.example.net', 80) do |http| 
    http.request_head('/index.html') 
end 

puts response.code.to_i < ERROR_CODE 

Welche true gibt, weil ich ein bekam 302 für die response.code.

+0

Ich versuche, die Dinge auf diese Weise, aber es wirft mich unbekannte Host-Ausnahme – Ph0en1x

+1

Ich kann das nicht duplizieren. Es funktioniert für mich mit Ruby 1.9.3. Sie zeigen nicht an, welche URL Sie erreichen möchten. Daher können wir Ihnen nicht helfen. –

Verwandte Themen