Примеры потоковых фильтров ввода / вывода Java - PullRequest
0 голосов
/ 19 апреля 2009

Я ищу пример кода, который демонстрирует, как создать фильтр, который распознает двоичные данные. Ссылки на примеры приветствуются.

Ответы [ 2 ]

1 голос
/ 19 апреля 2009

Для хорошего примера я бы посоветовал взглянуть на исходный код для java.io.DataInputStream. Этот класс показывает вам один способ декодирования примитивных типов и символьных строк из «двоичных» данных, из которых могут быть получены более сложные структуры.

Конечно, другие приложения могут использовать другие кодировки. Например, ASN.1 «отличительные правила кодирования» используются для приложений инфраструктуры открытых ключей. Lucene предоставляет хорошую документацию для своего формата файлов, который разработан для компактности.

Если у вас есть Sun JDK, поищите в ее верхнем каталоге «src.zip». Большинство IDE покажет вам исходный код для основных классов Java, если вы скажете им, где найти этот файл.

1 голос
/ 19 апреля 2009

Если вы имеете в виду примеры FilterInputStream / FilterOutputStream, то вам не нужно смотреть дальше JDK. Я расскажу о варианте входного потока ради аргумента, но то же самое относится и к выходным потокам.

Взгляните, например, на InflaterInputStream. Посмотрите на метод arry read () и обратите внимание, как в какой-то момент вызывается метод fill (), который, в свою очередь, читает из основного входного потока. Затем вокруг этого метода он вызывает Inflater для фактического превращения буфера «сырых» байтов, которые он извлекает из базового потока, в фактические байты, которые записываются в массив вызывающей стороны.

Следует учитывать, что FilterInputStream - это пустая трата пространства. До тех пор, пока вы можете определить свой InputStream для использования другого базового InputStream и во всех методах чтения, которые вы читаете из этого базового потока (учитывая, что в теории вам нужно только определить байтовый метод read ()), тогда в частности, расширение вашего класса FilterInputStream на самом деле не очень выгодно. Например, вот часть кода для входного потока, которая ограничивает количество байтов из базового потока, которое позволяет читателю (например, мы можем «разделить» поток на несколько подпотоков, что полезно например, при чтении из архивных файлов):

class LimitedInputStream extends InputStream {
  private InputStream in;
  private long bytesLeft;

  LimitedInputStream(InputStream in, long maxBytes) {
    this.in = in;
    this.bytesLeft = maxBytes;
  }

  @Override
  public int read() throws IOException {
    if (bytesLeft <= 0)
      return -1;
    int b = in.read();
    bytesLeft--;
    return b;
  }

  @Override
  public int read(byte b[], int off, int len) throws IOException {
    if (bytesLeft <= 0)
      return -1;
    len = (int) Math.min((long) len, bytesLeft);
    int n = in.read(b, off, len);
    if (n > 0)
      bytesLeft -= n;
    return n;
  }

  // ... missed off boring implementations of skip(), available()..
}

В этом случае в моем приложении мне ничего не нужно объявлять этим классом как FilterInputStream - фактически, это выбор между желанием вызвать in.read () или super.read () для получения базовых данных. ...!

...