Under what conditions does Java's Scanner.hasNextLine() block?

前端 未结 3 1128
伪装坚强ぢ
伪装坚强ぢ 2021-02-05 07:19

The javadoc for Scanner.hasNextLine() states:

Returns true if there is another line in the input of this scanner. This method m

3条回答
  •  我寻月下人不归
    2021-02-05 07:57

    Assuming by "decide if it will block" you mean that you want to know when it will bock.

    Have a look at where the input is assigned in the hasNextLine method

    String result = findWithinHorizon(linePattern(), 0);
    

    Now, have a look at the findWithinHorizon method

    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;
    }
    

    As you can see, it will loop infinitely until the end is reached, or until it succeed to read.

    findPatternInBuffer is a private method of the Scanner class that try to read the input.

    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;
    }
    

    I posted the whole method to give you a better idea of what I meant by "succeed to read".

提交回复
热议问题