简体   繁体   English

使用Java从套接字的流中读取多个流?

[英]read multiple streams from a stream of a socket using java?

Is there any way to read bytes randomly from a open socket stream? 有什么方法可以从打开的套接字流中随机读取字节吗? suppose i have opened a data stream in a website. 假设我已经在网站上打开了数据流。 traditional java classes giving me sequential access to the data. 传统的Java类使我可以顺序访问数据。 like a linked list. 就像一个链表。 i want to randomly read data like reading data from random positions of an array. 我想随机读取数据,例如从数组的随机位置读取数据。 Suppose if the data size is 2048 KB, i want to read from 0 to 1204 KB with 1 thread and simultaneously want to use another thread to read data from 1205 to 2048 KB. 假设数据大小为2048 KB,我想用1个线程从0读取到1204 KB,同时要使用另一个线程从1205到2048 KB读取数据。

so the bottom line is i want to multi thread the data reading process from a opened socket of a website. 所以最重要的是,我想从网站的打开套接字中对数据读取过程进行多线程处理。 The process has to be like Internet Download Manager. 该过程必须类似于Internet Download Manager。 Please give me some tutorials link if its possible.. 如果可能的话,请给我一些教程链接。

Reading from random locations in a stream from a website using multiple threads is not possible. 无法使用多个线程从网站流中的随机位置进行读取。 The data comes down as a linear stream and there is no standard way to go to different positions in the stream in multiple threads. 数据作为线性流下降,没有标准的方法可以在多个线程中到达流中的不同位置。 Multiple threads can download different files a the same time however. 但是,多个线程可以一次下载不同的文件。

The HTTPD protocol does support the Range: header although I'm not sure how many web servers support the behavior -- Apache does for example. HTTPD协议确实支持Range:标头,尽管我不确定有多少Web服务器支持该行为,例如Apache。 If supported, the server should respond with the following header: 如果支持,服务器应使用以下标头进行响应:

Accept-Ranges: bytes

The client then can ask for a particular offset/length of the file: 然后,客户端可以要求文件的特定偏移量/长度:

Range: bytes=21010-47021

With this you could have multiple threads downloading from different ranges at the same time but I'm not sure how this will speed up the download unless you are requesting from multiple servers. 这样一来,您可以同时从不同范围下载多个线程,但是除非您从多台服务器请求,否则我不确定这样做如何加快下载速度。 Most likely you will be running into disk and network limitations. 您很可能会遇到磁盘和网络限制。

The data from a socket arrives sequentially. 来自套接字的数据顺序到达。 You'd have to use some fairly large buffering to avoid this. 您必须使用一些较大的缓冲来避免这种情况。

I thinkt what you are asking about is the http header 我认为您要问的是http标头

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

Which will instruct the server to only send some of the file. 这将指示服务器仅发送一些文件。 You will then read the stream sequentially. 然后,您将顺序读取流。

See also How to assemble the file using the range header? 另请参见如何使用范围标头汇编文件?

edit: example 编辑:示例

This seems to work 这似乎有效

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
    }
}

It is important to note that not all servers support this, so check the isPartial variable. 重要的是要注意,并非所有服务器都支持此功能,因此请检查isPartial变量。 If it is false. 如果是假的。 The server does not support partial ranges and will give you the start of the file. 服务器不支持部分范围,将为您提供文件的开始。

You cannot read randomly over a socket. 您不能通过套接字随机读取。 In principle, you have two options: 原则上,您有两种选择:

  1. Read the whole data stream and put it an a buffer (a byte array for instance). 读取整个数据流,并将其放入缓冲区(例如,字节数组)。 Expose the buffer to each thread. 将缓冲区暴露给每个线程。

  2. Read the whole data stream in each thread independently, having each thread ignore everything that should not read. 独立读取每个线程中的整个数据流,让每个线程忽略所有不应读取的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM