2013-02-19 2 views
0

У меня есть случай, когда мне нужно заглянуть вперед в поток для существования определенного регулярного выражения, а затем прочитать данные из потока.mark и readAheadLimit

знак и сброс позволяет мне сделать это, но я столкнулся с вопросом, где знак становится недействительным, если readAheadLimit выходит за пределы размера текущего буфера.

Например: у меня есть BufferedReader с размером буфера 1k.

Позволяет сказать, что я нахожусь в положении 1000 (знак = 1000) в буфере, и мне нужно, чтобы проверить регулярное выражение в следующих 100 символов (readAheadLimit = 100).

Таким образом, при чтении момент Я пересекаю текущий размер буфера (1024), выделяется новый буфер и знак становится недействительным (не может быть сброшен), и данные передаются в новый буфер обычным способом.

Я думаю, что это намеченное поведение, но есть ли способ обойти это?

Цените свою помощь.

С уважением

ответ

1

Есть как минимум два варианта:

  1. Установить размер кэша по умолчанию гораздо больше, чем 1k:

    новый BufferedReader (originalReader, 1024 * 1024) // например, 1Mb

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

+0

1.Может не удовлетворять всем нашим случаям, поскольку мы передаем большой объем данных, и эти проверки могут быть часто необходимы. 2. Звучит интересно. Буду признателен, если вы сможете уточнить. Предполагаете ли вы, что мы читаем в буфер, а затем изменяем его размер на основе коэффициента загрузки, копируя предыдущее содержимое в новый буфер? –

+0

Отредактированный второй вариант в ответе. Коэффициент загрузки может вызывать OOM, если ваши данные действительно большие, поэтому вам все равно потребуется некоторое ограничение, чтобы сделать это в памяти. – Raman

+0

Возможно ли получить текущую позицию в буфере - где установлена ​​метка? Я хотел бы использовать это, чтобы определить, будет ли знак + readAheadLimit перетекать в следующий буфер. –

2

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

Нет это не является. Существующий буфер очищается и готовится для другого использования. не

и знак становится недействительным (не в состоянии сброса)

Нет это не так, если вы не вышли за пределы упреждающего чтения ограничить.

Вы, кажется, не читали API. Вы вызываете mark() с аргументом, в котором говорится, как далеко вперед вы хотите перейти до вызова reset(), в этом случае 100 байт, и API должен позволить вам сделать именно это. Поэтому, когда вы получаете до 100 символов вперед, вызовите reset(), и вы вернетесь туда, где находитесь, когда вы вызвали mark(). Как это происходит внутри, это не ваша проблема, но это обязательно должно произойти.

И как вы получили BufferedReader с 1k буфером? Значение по умолчанию - 4096.

+0

Спасибо за ваш ответ. Ну ... Я понимаю, что говорит api. Но сброс вызывает исключение IOException, и это произошло не из-за readAheadLimit. Что касается того, почему знак недействителен (я не уверен, что это предполагаемое поведение, но я думаю, что даже javadocs не слишком уверены в этом). «Последующие вызовы reset() будут ** пытаться ** переместить поток в эту точку. btw, BufferedReader (Reader in, int sz) позволяет установить размер буфера, который по умолчанию равен 8k, если я не –

+1

@falloficarus Ну, что я получаю, это то, почему вы так резко уменьшили размер буфера. Нет никакой пользы. Если вы получаете IOException, вы должны были разместить трассировку стека в своем вопросе. Сначала мы слышали об этом здесь , в комментарии к ответу. – EJP