Предел считывания метки буферизованного входного потока

Я изучаю, как использовать InputStream. Я пытался использовать знак для BufferedInputStream, но когда я пытаюсь reset, у меня есть эти исключения:

java.io.IOException: Resetting to invalid mark

Я думаю, это означает, что мой предел чтения метки установлен неправильно. На самом деле я не знаю, как установить предел чтения в методе(). Я пробовал вот так:

is = new BufferedInputStream(is);
is.mark(is.available());

Это тоже неправильно.

is.mark(16);

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

Ответ 1

mark иногда полезен, если вам нужно проверить несколько байтов за пределами того, что вы прочитали, чтобы решить, что делать дальше, затем вы reset вернитесь к метке и вызовите подпрограмму, которая ожидает, что указатель файла будет в начале этой логической части ввода. Я не думаю, что это действительно предназначено для других.

Если вы посмотрите на javadoc для BufferedInputStream, он говорит

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

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

Ответ 2

Это будет прочитано 5 раз из того же BufferedInputStream.

for (int i=0; i<5; i++) {
   inputStream.mark(inputStream.available()+1);
   // Read from input stream
   Thumbnails.of(inputStream).forceSize(160, 160).toOutputStream(out);
   inputStream.reset();
}

Ответ 3

Значение, которое вы передаете на mark(), - это сумма назад, которая вам понадобится reset. если вам нужно reset в начале потока, вам понадобится буфер размером с весь поток. это, вероятно, не большой дизайн, поскольку он не будет хорошо масштабироваться для больших потоков. если вам нужно дважды прочитать поток, и вы не знаете источник данных (например, если это файл, вы можете просто повторно открыть его), то вам, вероятно, следует скопировать его в временный файл, прочитайте его по своему усмотрению.