2013-06-11 3 views
1

В соответствии с this documentation он говорит, что:сброса() на InputStream без знака()

void reset()

Репозиционирования этого поток в положение, в то время, когда метод mark в последний раз называемого в данном входном потоке.

Но что произойдет, если mark() никогда не назывался? Будет ли он сбрасываться до начала потока (это то, что я хочу), или оно будет неопределенным? Кроме того, когда я смотрю на документацию для markSupported() он говорит:

Тесты, если этот входной поток поддерживает mark и сбросаmethods.

Таким образом, это также проверяет сброс, что указывает на то, что сброс также может не поддерживаться. Безопасно ли в этом случае, если я просто закрою и снова открою поток в своем собственном коде сброса?

+1

Вы попробовали? (Ссылаясь на «Но что произойдет, если знак() никогда не вызывался?») – Fildor

+0

Попытка привести пример к конкретной реализации - это не то же самое, что работать со стандартом. И да, я знаю, что он работает в настоящий момент, но может не сработать, если я продолжу класс с другой реализацией. – Devolus

+1

Я вижу, поэтому вы хотите сделать код независимым от конкретной Stream-реализации, не так ли? Если я правильно помню, сброс только имеет смысл, если знак поддерживается. И я мрачно помню, что читал, что если он поддерживается, и знак не был вызван, то сброс либо выведет исключение IOException, либо перемотается в начало. – Fildor

ответ

2

documentation дает ответ; к сожалению, это не однозначный ответ:

Общий договор reset является:

Если метод markSupported возвращает true, то:

  • Если метка метод не был вызван поскольку поток был создан, или количество байтов, считанных из потока, поскольку последний последний раз был вызван , больше, чем аргумент для отметки последнего последнего вызова, тогда IOException может быть rown.

  • Если такой IOException не выбрасывается, а затем поток сбрасывается в состояние таким образом, что все байты читать с момента последнего вызова, чтобы отметить (или с начала файла, если метка не была вызвана) будет , который будет добавлен к последующим вызывающим абонентам метода чтения, за которым последуют любые байты, которые в противном случае были бы следующими входными данными по состоянию на времени вызова для сброса.

Если метод возвращает markSupported false, то:

  • Вызов сброса может бросить IOException.

  • Если IOException не выбрасывается, то поток сбрасывается в фиксированное состояние, которое зависит от конкретного типа входного потока и от того, как оно было создано: . Байты, которые будут переданы последующим вызывающим абонентам метода чтения, зависят от конкретного типа входного потока.

Другими словами, если markSupported() возвращает true то поток может либо бросить IOException или вести себя, как вы хотите. Если markSupported() возвращает false, то он либо выдаст исключение, либо будет вести себя по-разному.

Короче говоря, контракт на интерфейс не гарантирует, что реализация будет вести себя так, как вы этого хотите. Кажется, что самая безопасная вещь - проверить для markSupported() и установить отметку в начале входного потока, если она поддерживается. Если он не поддерживается, вам нужно либо поэкспериментировать, чтобы обеспечить выполнение функций работы, либо, как ожидалось, или создать средство воссоздания потока.

+0

По крайней мере, [один] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/io/StringBufferInputStream.java#StringBufferInputStream.reset%28%29) реализация библиотеки сбрасывается до начала, если знак не установлен. – selig

+0

@selig: Фактически, это просто сбрасывается до начала, независимо от любого вызова метки (и для этой реализации 'markSupported()' возвращает 'false'). Это возможное поведение в соответствии с документированным контрактом, оно просто не гарантируется для всех реализаций. – ig0774

2

Поведение reset() без вызова mark() не очень stricly указано, но из JavaDoc:

Общий договор сброса:

  • Если метод markSupported возвращает истину, затем:

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

  • Если такое исключение IOException не выбрасывается, поток сбрасывается в состояние, так что все байты, считанные с момента последнего вызова для отметки (или с момента запуска файла, если знак не был вызван) будет повторно добавлен к последующим вызывающим абонентам метода чтения, за которыми последуют любые байты, которые в противном случае были бы следующими входными данными со времени вызова для сброса.

+0

Этот ответ был занижен, потому что ..? :-(Я согласен с тем, что принятый ответ более сложный, но я не вижу ничего неправильного или ложного здесь ... – haraldK

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