2012-05-08 4 views
0

Есть ли способ случайно читать байты из открытого потока сокетов? предположим, что я открыл поток данных на веб-сайте. традиционные классы Java, дающие мне последовательный доступ к данным. как связанный список. Я хочу случайным образом читать данные, такие как чтение данных из случайных позиций массива. Предположим, что если размер данных составляет 2048 КБ, я хочу читать от 0 до 1204 КБ с 1 потоком и одновременно хочу использовать другой поток для чтения данных с 1205 до 2048 КБ.читать несколько потоков из потока сокета с помощью java?

поэтому в нижней строке я хочу, чтобы многопоточность процесса чтения данных из открытого сокета веб-сайта. Этот процесс должен быть похож на Internet Download Manager. Пожалуйста, дайте мне ссылку на учебники, если это возможно.

+0

Короткий ответ: нет, потому что потоки не являются случайным доступом. –

+0

Если вы хотите написать свой собственный менеджер загрузок, вам следует прочитать HTTP-запросы. Потоки не работают так, как вы хотите. –

+0

Тогда можно ли указать местоположение байта в запросе? , поэтому я смогу использовать 2 или более потока для чтения данных из разных мест одного и того же потока по одному. Будет ли это приносить прибыль? @PhilippReichart –

ответ

3

Чтение из случайных мест в потоке с веб-сайта с использованием нескольких потоков невозможно. Данные опускаются как линейный поток, и нет стандартного способа перехода на разные позиции в потоке в нескольких потоках. Несколько потоков может скачать различные файлы в то же время.

Протокол HTTPD поддерживает Range: header, хотя я не уверен, сколько веб-серверов поддерживает поведение - например, Apache. Если поддерживается, сервер должен отвечать следующим заголовком:

Accept-Ranges: bytes 

Затем клиент может запросить конкретное смещение/длину файла:

Range: bytes=21010-47021 

С этим может иметь несколько потоков одновременно загружая из разных диапазонов, но я не уверен, как это ускорит загрузку, если вы не запрашиваете несколько серверов. Скорее всего, вы столкнетесь с дисковыми и сетевыми ограничениями.

1

Данные из гнезда поступают последовательно. Чтобы избежать этого, вам придется использовать довольно большую буферизацию.

0

Вы не можете читать случайно по сокету. В принципе у вас есть два варианта:

  1. Прочитайте весь поток данных и поместите его в буфер (например, массив байтов). Откройте буфер для каждого потока.

  2. Прочитайте весь поток данных в каждом потоке независимо, каждый поток игнорирует все, что не должно читать.

1

Я thinkt, что вы спрашиваете о том, HTTP-заголовок

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

Которая дает команду серверу посылать только часть файла. Затем вы будете читать поток последовательно.

Смотрите также How to assemble the file using the range header?

редактирования: пример

Это похоже на работу

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 переменную. Если это неверно.Сервер не поддерживает частичные диапазоны и даст вам начало файла.

+0

На самом деле я новичок в java и не имею опыта работы в сети. Итак, если вы можете дать ma пример того, что вы только что сказали, используя java, это будет очень полезно. :) –

+0

Я добавил пример –

Смежные вопросы