2016-03-05 1 views
0

Учитывая InputStream, мне нужен инструмент, где я вызываю next(), текущие блоки выполнения до 50 байтов, накопленные в потоке, после чего next() возвращается с byte[] длиной 50, содержащей соответствующие данные.Нарисовать данные из InputStream с каждой фиксированной длиной байта?

Удивительно сложно найти правильные фразы в Google, поэтому я здесь.

Спасибо.

+0

Вы хотите, чтобы 'InputStream' вел себя так, потому что вы хотите, чтобы' next() 'call возвращал данные в ожидающий код или я что-то не понимаю? –

+0

Ты совершенно прав, у меня было это неправильно в голове. Редактирование вопроса. – eyal3400

ответ

0

Вы должны обязательно обратиться к стандартной библиотеке JDK за отличными классами для чтения и записи IO. Но ваше требование было довольно интересным. Вам нужен интерфейс «итератор» для входного потока. Итак, вот моя попытка. Конечно, возможны некоторые оптимизации, но, надеюсь, это хорошо объясняет эту идею. Сообщите мне, если это то, что вы ищете. Я признаю, что в контракте есть тонкое изменение в том, что метод hasNext() блокирует базовый поток ввода. Надеюсь, все в порядке.

import java.io.BufferedInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.Arrays; 
import java.util.Iterator; 
import java.util.function.Consumer; 

/** An attempt for: 
* http://stackoverflow.com/questions/35817251/draw-data-from-inputstream-every-fixed-byte-length 
* <b>This class is NOT thread safe.</b> 
* Created by kmhaswade on 3/5/16. 
*/ 
public class InputStreamIterator extends BufferedInputStream implements Iterator<byte[]> { 

    private final InputStream in; 
    private final byte[] bytes; 
    private int bytesRead; 
    /** 
    * Returns a buffered input stream that "iterates" over a given stream. Follows the decorator pattern. 
    * @param in the input stream that should be buffered 
    * @param n 
    */ 
    public InputStreamIterator(InputStream in, int n) { 
     super(in); 
     this.in = in; 
     if (n <=0 || n > Integer.MAX_VALUE) 
      throw new IllegalArgumentException("illegal value: " + n); 
     bytes = new byte[n]; 
    } 

    @Override 
    public boolean hasNext() { 
     try { 
      bytesRead = super.read(this.bytes); 
      if (bytesRead == -1) { 
       this.close(); 
       return false; 
      } 
      return true; 
     } catch (IOException e) { 
      throw new RuntimeException(e); // could be handled better ... 
     } 
    } 

    @Override 
    public byte[] next() { 
     if (bytes.length == bytesRead) 
      return bytes; 
     else 
      return Arrays.copyOf(bytes, bytesRead); 
    } 

    @Override 
    public void remove() { 
     throw new RuntimeException("no way to push back yet"); 
    } 

    @Override 
    public void forEachRemaining(Consumer<? super byte[]> action) { 
     throw new RuntimeException("not yet implemented"); 
    } 

    public static void main(String[] args) { 
     InputStreamIterator itIn = new InputStreamIterator(System.in, 50); 
     while (itIn.hasNext()) { 
      byte[] bs = itIn.next(); 
      for (byte b : bs) { 
       System.out.println("byte read: " + b); 
      } 
     } 
    } 
} 
+0

Вот что мне нужно, спасибо. – eyal3400

1

Там нет такого инструмента в JDK, но вы можете просто обернуть InputStream в DataInputStream и называют readFully(byte[]) на нем:

InputStream is = // ... 
DataInputStream dis = new DataInputStream(is); 
byte[] bytes = new byte[50]; 
dis.readFully(bytes); 
// "bytes" now contains exactly 50 bytes from the stream 

Чтобы иметь класс с методом next(), реализовать Iterator интерфейс и сделать это внутренне.

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