System.in中的read()方法


感謝大佬:https://blog.csdn.net/u012345283/article/details/39027745

大家先來看如下這個程序

public class TestInputStream {
	public static void main(String args[]) throws IOException {
		InputStream in = System.in;
		int a = in.read();
		System.out.println(a);
		a = in.read();
		System.out.println(a);
		a = in.read();
		System.out.println(a);
	}
}

大家先來看如下這個程序

問題一:如果輸入”a“,那么會輸出什么呢?

事實上我輸入“a”,它並沒有反應

問題二:如果輸入“a”並按下了回車,那么會輸出什么呢?

97 13 10,並且程序結束運行

問題三:如果只按下回車,那么會輸出什么呢?

13 10,並且程序未結束運行

問題四:如果輸出“abc”,那么會輸出什么呢?

97 98 99

好了,例子將完了,下面來分析下上面4種情況

首先我們需要知道System.in到底是什么?

直接輸出System.in我們可以發現它是一個BufferedInputStream

那么BufferedInputStream.read()是如何運作的?

我們可以粗略的掃一下源碼

    private void fill() throws IOException {
        byte[] buffer = getBufIfOpen();
	if (markpos < 0)
	    pos = 0;		/* no mark: throw away the buffer */
	else if (pos >= buffer.length){	/* no room left in buffer */
	// 這里是設置了mark之后的操作,不需要關心
	}
        count = pos;
	int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
        if (n > 0)
            count = n + pos;
    }

其中buffer是BufferedInputStream的緩沖區,read(byte[] b, int off, int len)方法是從底層輸入流讀取數據,該方法為阻塞方法,那么什么時候會返回呢?

調試進去發現,System.in中底層輸入流為FileInputStream,根據官方文檔上的描述:

1、如果 len 不為 0,則在輸入可用之前,該方法將阻塞

2、返回讀入緩沖區的字節總數,如果因為已經到達文件末尾而沒有更多的數據,則返回 -1。 

那么對於控制台輸入該如何判斷達到“文件末尾”呢?通過回車來提交數據,並告訴程序提交完畢。


下面針對上面的問題一一解答

1、由於在控制台輸入時,按下回車鍵才代表輸入完成,輸入的內容才會提交到read()方法,所以按下回車之前,程序是不知道你輸入了什么的

2、輸入"a"后按下回車,這時候read()方法讀到了數據,此時buffer中的數據應該是97 13 10,也就是字符'a','\r', '\n',並且read()方法每次只能從緩沖區中讀出一個字符,三次read()就剛好讀出這3個字符,之后程序就結束了。

3、只按下回車,此時從流中只讀到了"\r"和"\n",由於沒有足夠的輸入,那么第三次調用read()時阻塞

4、輸入"abc",此時從流中讀到"a","b","c","\r","\n",由於只read()了3次,那么讀出abc,\r和\n仍在buffer中







補充:
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM