Предел чтения метки буферизованного входного потока - PullRequest
10 голосов
/ 22 декабря 2011

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

java.io.IOException: Resetting to invalid mark

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

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

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

is.mark(16);

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

Ответы [ 3 ]

6 голосов
/ 22 декабря 2011

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

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

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

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

1 голос
/ 01 апреля 2015

Это будет читать 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();
}
0 голосов
/ 22 декабря 2011

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

...