Влияние на исходный InputStream после переноса с помощью BufferedInputStream

Предположим, у меня есть метод, который принимает InputStream.

Этот метод должен обернуть этот InputStream с помощью BufferedInputStream, чтобы использовать его функции пометки и сброса. Тем не менее, переданный в InputStream может по-прежнему использоваться вызывающей стороной метода.

public static void foo(InputStream is) throws Exception {
    BufferedInputStream bis = new BufferedInputStream(is);
    int b = bis.read();
}

public static void main(String[] args) {


    try {
        InputStream is = new FileInputStream(someFile);
        foo(is);
        int b = is.read(); // return -1
    }catch (Exception e) {
        e.printStackTrace();
    }
}

Мои вопросы: что именно происходит с исходным InputStream, когда BufferedInputStream читается (или инициализируется)?

Я предполагаю, что исходный InputStream также будет двигаться вперед, если BufferedInputStream будет прочитан. Однако после отладки моего кода я обнаружил, что вместо этого InputStream будет возвращать -1 при чтении.

Если исходный InputStream не читается после такого процесса, как мне достичь своей цели:

InputStream is;
foo(is);               // Method only take in generic InputStream object
                       // Processing of the passed in InputStream object require mark and reset functionality
int b = is.read();     // Return the next byte after the last byte that is read by foo()

РЕДАКТИРОВАТЬ: Я полагаю, что то, о чем я прошу, является довольно общим и поэтому требует большой работы. Что касается того, над чем я работаю, мне на самом деле не нужна полная возможность отметки и сброса, поэтому я нашел небольшой обходной путь. Тем не менее, я оставлю вторую часть вопроса здесь, так что не стесняйтесь решать эту проблему :).


person Zekareisoujin    schedule 22.01.2014    source источник


Ответы (5)


Размер буфера по умолчанию для BufferedInputStream равен 8192, поэтому, когда вы читаете из BufferedInputStream, он пытается заполнить свой буфер. Итак, если вам нужно прочитать из вашего InputStream байт меньше, чем из bufferSize, то все содержимое вашего InputStream читается в буфер, поэтому вы получаете -1 после чтения из BufferedInputStream

Взгляните на BufferedInputStream исходный код: http://www.docjar.com/html/api/java/io/BufferedInputStream.java.html

person Alexander Tokarev    schedule 22.01.2014

http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html#BufferedInputStream%28java.io.InputStream%29

Похоже, BufferedInputStream использует InputStream для действий, выполняемых с потоком данных. Класс Buffered просто реализует буферный массив для внутреннего использования.

Не уверен, что вы могли бы использовать вместо этого, кроме, возможно, копирования InputStream, чтобы у вас был второй объект для вызова.

person Gorbles    schedule 22.01.2014

BufferedInputStream будет предварительно загружать данные из базовой позиции InputStream в пакетном режиме, что приведет к соответствующему перемещению базовой позиции InputStream. Если размер буфера достаточен для использования всех данных из базового потока за один раз, вы вполне можете наблюдать описанное вами поведение.

person bobah    schedule 22.01.2014

Две вещи:

  1. Любой API, который принимает поток в качестве входного параметра, вероятно, будет использовать этот поток, поэтому для вызывающей стороны неразумно ожидать, что поток останется в каком-либо пригодном для использования состоянии. Возможно, для потоковых классов Java было бы лучше каким-то образом обеспечить единое владение, чтобы сделать это более понятным.

  2. В качестве особого случая BufferedInputStream будет использовать базовый поток, который он «обертывает», потому что он достигает (ограниченной формы) метки и сброса путем буферизации чтения блоков, как указывали другие.

person Judge Mental    schedule 22.01.2014

private static class MybufferedInputStream extends BufferedInputStream {
    public MybufferedInputStream(InputStream in) {
        super(in);
    }

    public int getBufferSize(){
        int i=0;
        for (Byte byte1 : super.buf) {
            if (byte1!=0) {
                i++;
            }
        }
        return i;
    }
}

затем вы можете вызвать getBufferSize() после read(), чтобы увидеть разницу между маленьким файлом и большим файлом.

person user3389182    schedule 09.11.2015