0

開いているソケットストリームからランダムにバイトを読み取る方法はありますか?Webサイトでデータストリームを開いたとします。データへのシーケンシャルアクセスを提供する従来のJavaクラス。リンクリストのように。配列のランダムな位置からデータを読み取るように、ランダムにデータを読み取りたい。データサイズが2048KBの場合、1つのスレッドで0〜1204 KBを読み取り、同時に別のスレッドを使用して1205〜2048KBのデータを読み取りたいとします。

つまり、重要なのは、Webサイトの開いたソケットからのデータ読み取りプロセスをマルチスレッド化することです。プロセスは、インターネットダウンロードマネージャーのようなものでなければなりません。可能であれば、チュートリアルのリンクを教えてください。

4

4 に答える 4

3

複数のスレッドを使用して Web サイトからストリーム内のランダムな場所から読み取ることはできません。データは線形ストリームとして生成され、複数のスレッドでストリーム内の異なる位置に移動する標準的な方法はありません。ただし、複数のスレッド異なるファイルを同時にダウンロードする可能性があります。

HTTPD プロトコルはRange:ヘッダーをサポートしていますが、この動作をサポートしている Web サーバーの数はわかりません。たとえば、Apache はサポートしています。サポートされている場合、サーバーは次のヘッダーで応答する必要があります。

Accept-Ranges: bytes

クライアントは、ファイルの特定のオフセット/長さを要求できます。

Range: bytes=21010-47021

これにより、異なる範囲から同時に複数のスレッドをダウンロードできますが、複数のサーバーから要求していない限り、ダウンロードがどのように高速化されるかはわかりませんほとんどの場合、ディスクとネットワークの制限に直面するでしょう。

于 2012-05-08T13:16:38.820 に答える
1

あなたが質問しているのはhttpヘッダーだと思います

Accept-Ranges: bytes
Range: bytes=0-8999

これは、ファイルの一部のみを送信するようにサーバーに指示します。次に、ストリームを順番に読み取ります。

範囲ヘッダーを使用してファイルをアセンブルする方法も参照してください。

編集:例

これはうまくいくようです

public static void main(String[] args) throws MalformedURLException, IOException {
    URLConnection conn = new URL("http://ftp.debian.org/debian/dists/stable/Contents-i386.gz")
            .openConnection();
    conn.addRequestProperty("Accept-Ranges","bytes");
    conn.addRequestProperty("Range", "bytes=8000000-16000000");
    InputStream input = conn.getInputStream();
    List<String> serverranges = conn.getHeaderFields().get("Accept-Ranges");
    boolean ispartial = serverranges != null && serverranges.get(0).equals("bytes");
    byte[] b = new byte[1024];
    int l ;
    System.out.println(ispartial);
    while((l=input.read(b, 0, b.length))>0){
        // if isPartial=true, we have server support. We received partial file.
        //do stuff with b,l
    }
}

すべてのサーバーがこれをサポートしているわけではないことに注意することが重要です。したがって、isPartial変数を確認してください。それが偽の場合。サーバーは部分的な範囲をサポートしておらず、ファイルの先頭を提供します。

于 2012-05-08T13:24:01.607 に答える
1

ソケットからのデータは順次到着します。これを回避するには、かなり大きなバッファリングを使用する必要があります。

于 2012-05-08T13:16:53.583 に答える
0

ソケットを介してランダムに読み取ることはできません。原則として、次の 2 つのオプションがあります。

  1. データ ストリーム全体を読み取り、それをバッファー (たとえば、バイト配列) に配置します。バッファを各スレッドに公開します。

  2. 各スレッドでデータ ストリーム全体を個別に読み取り、各スレッドが読み取らないものをすべて無視するようにします。

于 2012-05-08T13:22:04.697 に答える