12

Ruby の Net::HTTP のメソッドは、Web ページの本文を読み取ることに関しては、オール オア ナッシングのようです。たとえば、本文の最初の 100 バイトだけを読み取るにはどうすればよいでしょうか。

要求されたファイルが利用できない場合、応答の本文で短いエラー メッセージを返すコンテンツ サーバーから読み取ろうとしています。ファイルがそこにあるかどうかを判断するには、本文を十分に読み取る必要があります。ファイルは巨大なので、ファイルが利用可能かどうかを確認するためだけに全身を取得したくありません。

4

6 に答える 6

13

これは古いスレッドですが、私の調査によれば、RubyでHTTPを介してファイルの一部のみを読み取る方法の問題は、まだほとんど答えられていません。これが私がNet::HTTPに少しパッチを当てることによって思いついた解決策です:

require 'net/http'

# provide access to the actual socket
class Net::HTTPResponse
  attr_reader :socket
end

uri = URI("http://www.example.com/path/to/file")
begin
  Net::HTTP.start(uri.host, uri.port) do |http|
    request = Net::HTTP::Get.new(uri.request_uri)
    # calling request with a block prevents body from being read
    http.request(request) do |response|
      # do whatever limited reading you want to do with the socket
      x = response.socket.read(100);
      # be sure to call finish before exiting the block
      http.finish
    end
  end
rescue IOError
  # ignore
end

レスキューは、HTTP.finishを時期尚早に呼び出したときにスローされるIOErrorをキャッチします。

参考までに、オブジェクト内のソケットは実際のHTTPResponseオブジェクトではありませんIO(これはと呼ばれる内部クラスです)が、必要なメソッドBufferedIOを模倣するためにモンキーパッチを適用するのも非常に簡単です。IOたとえば、私が使用していた別のライブラリ(exifr)には、readchar簡単に追加できるメソッドが必要でした。

class Net::BufferedIO
  def readchar
    read(1)[0].ord
  end
end
于 2011-12-21T22:55:41.540 に答える
12

HTTPHEADリクエスト (RubyNet::HTTP::Headメソッド) を使用してリソースが存在するかどうかを確認し、2xx または 3xx の応答が得られた場合にのみ続行するべきではありませんか? これは、ドキュメントが利用できない場合に 4xx エラー コードを返すようにサーバーが構成されていることを前提としています。私はこれが正しい解決策であると主張します。

別の方法として、HTTP ヘッドを要求content-lengthし、結果のヘッダー値を確認することもできます。サーバーが正しく構成されていれば、短いメッセージと長いドキュメントの長さの違いを簡単に見分けることができるはずです。別の方法:content-rangeリクエストにヘッダー フィールドを設定します (ここでも、サーバーが HTTP 仕様に基づいて正しく動作していることを前提としています)。

GET リクエストを送信した後にクライアントで問題を解決するのは適切ではないと思います。その時点までに、ネットワークは重労働を終えており、無駄なリソースを実際に節約することはできません。

参考:httpヘッダーの定義

于 2008-09-17T12:43:03.110 に答える
3

私はこれを一度やりたかったのですが、私が考えることができる唯一のことは、長さパラメーターを受け入れるようにNet::HTTP#read_bodyandNet::HTTP#read_body_0メソッドにモンキーパッチを適用することであり、前者では、長さパラメーターをread_body_0メソッドに渡すだけで、長さバイト。

于 2008-09-17T14:46:07.340 に答える
2

Net::HTTPResponse#read_bodyHTTP リクエストの本文をチャンクで読み取るには、次のように使用する必要があります。

http.request_get('/large_resource') do |response|
  response.read_body do |segment|
    print segment
  end
end
于 2008-09-17T12:38:37.147 に答える
2

コンテンツ サーバーが短いエラー ページのみを返しますか?

また、 を 404 のような適切なものに設定しませんか。その場合、 にアクセスするときに発生する派生例外 (おそらく) をHTTPResponseトラップできます。HTTPClientErrorHTTPNotFoundNet::HTTP.value()

エラーが発生した場合、ファイルが存在しない場合は 200 が表示され、ファイルのダウンロードが開始され、接続を閉じることができます。

于 2008-09-17T12:28:54.127 に答える
-4

できません。しかし、なぜあなたはする必要があるのですか?ページが単にファイルが利用できないと言っているだけなら、巨大なページにはなりません (つまり、定義上、ファイルは存在しません)。

于 2008-09-17T12:27:36.893 に答える