zoukankan      html  css  js  c++  java
  • 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',' ', ' ',并且read()方法每次只能从缓冲区中读出一个字符,三次read()就刚好读出这3个字符,之后程序就结束了。

    3、只按下回车,此时从流中只读到了" "和" ",由于没有足够的输入,那么第三次调用read()时阻塞

    4、输入"abc",此时从流中读到"a","b","c"," "," ",由于只read()了3次,那么读出abc, 和 仍在buffer中







    补充:
    在这里插入图片描述

  • 相关阅读:
    Informix IDS 11零碎规画(918考试)认证指南,第 7 部分: IDS复制(15)
    Informix IDS 11琐屑管理(918考试)认证指南,第 7 局部: IDS复制(10)
    近期招聘
    Classes 单元下的公用函数目录
    Graphics 单元下的公用函数目录
    CnPack 使用的组件命名约定
    Windows 单元下的公用函数目录(RZ_)
    Variants 单元下的公用函数目录
    StrUtils 单元下的公用函数目录
    Math 单元下的公用函数目录
  • 原文地址:https://www.cnblogs.com/tfxz/p/12621634.html
Copyright © 2011-2022 走看看