Предполагая, что «решить если он будет блокировать «, вы имеете в виду, что хотите знать, когда он будет работать.
Посмотрите, где вход назначен в методе hasNextLine
String result = findWithinHorizon(linePattern(), 0);
Теперь посмотрим на findWithinHorizon
метод
public String findWithinHorizon(Pattern pattern, int horizon) {
ensureOpen();
if (pattern == null)
throw new NullPointerException();
if (horizon < 0)
throw new IllegalArgumentException("horizon < 0");
clearCaches();
// Search for the pattern
while (true) { //it may block here if it never break
String token = findPatternInBuffer(pattern, horizon);
if (token != null) {
matchValid = true;
return token;
}
if (needInput)
readInput();
else
break; // up to end of input
}
return null;
}
Как вы можете видеть, это будет цикл бесконечно до конца или до тех пор, пока ему не удастся его прочитать.
findPatternInBuffer
- частный метод класса Scanner
, который пытается прочитать ввод.
private String findPatternInBuffer(Pattern pattern, int horizon) {
matchValid = false;
matcher.usePattern(pattern);
int bufferLimit = buf.limit();
int horizonLimit = -1;
int searchLimit = bufferLimit;
if (horizon > 0) {
horizonLimit = position + horizon;
if (horizonLimit < bufferLimit)
searchLimit = horizonLimit;
}
matcher.region(position, searchLimit);
if (matcher.find()) {
if (matcher.hitEnd() && (!sourceClosed)) {
// The match may be longer if didn't hit horizon or real end
if (searchLimit != horizonLimit) {
// Hit an artificial end; try to extend the match
needInput = true;
return null;
}
// The match could go away depending on what is next
if ((searchLimit == horizonLimit) && matcher.requireEnd()) {
// Rare case: we hit the end of input and it happens
// that it is at the horizon and the end of input is
// required for the match.
needInput = true;
return null;
}
}
// Did not hit end, or hit real end, or hit horizon
position = matcher.end();
return matcher.group();
}
if (sourceClosed)
return null;
// If there is no specified horizon, or if we have not searched
// to the specified horizon yet, get more input
if ((horizon == 0) || (searchLimit != horizonLimit))
needInput = true;
return null;
}
Я отправил весь метод, чтобы дать вам лучшее представление о том, что я имел в виду «удастся прочитать».
Это хороший ответ и объяснение того, почему это работает как это происходит. Но это как бы позволяет избежать актуального вопроса. – aioobe
@aioobe Я не думаю, что это избегает вопроса. Когда вы создаете экземпляр Scanner, вы знаете, из какого источника он получает вход, поэтому вы знаете, будет ли он блокироваться или нет. Если вам предоставлен экземпляр Scanner, не зная его источник ввода, вы не можете знать, будет ли он блокироваться. – Eran
@aloobe: Вы удалили свой ответ так быстро, что я не мог опубликовать этот комментарий для комментариев здесь, но я хотел бы отметить, что ваша общая идея кажется звуковой - нам нужен только лучший класс-оболочка, который фактически использовал ['InputStream. available() '] (http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available%28%29), чтобы проверить, сколько символов он может заглянуть вперед, не блокируя. (Конечно, это будет работать только на практике, если поток, который вы читаете, фактически реализует полезный метод 'available()', реализация по умолчанию всегда возвращает ноль.) –