博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java字节流read函数
阅读量:4615 次
发布时间:2019-06-09

本文共 3026 字,大约阅读时间需要 10 分钟。

问题引入

做Java作业从标准输入流获取用户输入,用到了System.in.read(),然后出现了bug。

//随机生成一个小写字母,用户猜5次,读取用户输入,并判断是否猜对import java.io.IOException;public class LetterGuessing {    public static void main(String[] args) throws IOException {        char ch,answer;        //随机生成字母        answer=(char)(Math.random()*26+'a');        System.out.print("请输入一个小写字母:");        for(int i=1;i<=5;i++) {            //获取用户输入,可能抛出异常            ch=(char)System.in.read();            //比较大小            if(ch == answer){                System.out.println("恭喜,正确!用了"+i+"次猜对");                break;            }            else if(ch > answer)                System.out.println("您猜大了,还有"+ (5-i) +"次机会");            else                System.out.println("您猜小了,还有"+ (5-i) +"次机会");        }    }}

输入字符'a',按下Enter,却没有等我下次输入,循环就运行了三次。

问题来源

System.in.read()按字节读,一次读入一个字节。后边有详细讲解。

经调试,可知三次循环中ch分别为a,\r,\n

为什么a+Enter,会变成a\r\n呢

Windows下存在两种文件读写方式,一个是二进制方式,另一种是文本方式

文本方式中写时“换行”会变成“回车-换行”,即\r\n;读时“回车-换行”会变成“换行”。

二进制方式中读写是严格按照一个字节一个字节的方式进行的。

在这里虽然没有用到文件,但道理应该是一样的

read()函数是按照一个字节一个字节读取的,即二进制方式。

可能可以推导出,我们向输入流中输入数据默认是按照文本方式。

解决方法

方法一

在代码第10行后,加两行System.in.read();

目的是读取掉输入流中的/r和/n。

这种方法的局限性就是输入字母前后不能加空格,因为它不会使空格从输入流中删除。

方法二

不用read()读取,用以下代码代替

import java.util.Scanner;Scanner input=new Scanner(System.in);ch=input.next().charAt(0);

这种方法就比较好,读取字符串(忽略空格和换行,空格和换行不会留在输入流里),然后取字符串的第一个字符。

知识点

System.in

官方文档:https://docs.oracle.com/javase/10/docs/api/java/lang/System.html#in

System是个类,in是System的一个成员,官方介绍如下:

public static final InputStream in

The “standard” input stream. This stream is already open and ready to supply input data. Typically this stream corresponds to keyboard input or another input source specified by the host environment or user.

in是一个InputStream类型的对象,所以只需要了解InputStream即可。

InputStream

官方文档: https://docs.oracle.com/javase/10/docs/api/java/io/InputStream.html

public abstract class InputStream   //抽象类extends Object          //继承Object类implements Closeable    //实现Closeable接口

官方介绍如下:

This abstract class is the superclass of all classes representing an input stream of bytes.

翻译为:这个抽象类是所有字节流类的父类。

字节流的含义:读取方式为一个字节一个字节地读取,而字符流是二个字节二个字节的读。

Applications that need to define a subclass of InputStream must always provide a method that returns the next byte of input.

翻译为:需要定义一个InputStream子类的应用必须提供一个返回输入下一字节的方法(函数)。

read()

官方文档:https://docs.oracle.com/javase/10/docs/api/java/io/InputStream.html#read()

public abstract int read()                 throws IOException

Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to255.

这个是重点,它返回下一字节的ASCII码

If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

A subclass must provide an implementation of this method.

Returns:

the next byte of data, or -1 if the end of the stream is reached.

Throws:

IOException - if an I/O error occurs.

作者:

本文为作者原创,转载请注明出处:

欢迎转发和评论

转载于:https://www.cnblogs.com/chouxianyu/p/11270035.html

你可能感兴趣的文章
带CookieContainer进行post
查看>>
C语言学习笔记--字符串
查看>>
CSS-上下文选择器
查看>>
ionic repeat 重复最后一个时要执行某个函数
查看>>
1.初识代码审计-基础
查看>>
[Vue-rx] Stream an API using RxJS into a Vue.js Template
查看>>
解决VC几个编译问题的方法——好用
查看>>
SPOJ #11 Factorial
查看>>
City Upgrades
查看>>
“人少也能办大事”---K2 BPM老客户交流会
查看>>
关于七牛进行图片添加文字水印操作小计
查看>>
DataSource数据库的使用
查看>>
CentOS开启samba实现文件共享
查看>>
MSSQL使用sqlbulkcopy批量插入数据
查看>>
证明一个数能被3整除,当且仅当它的各位数的和能被3整除
查看>>
2018秋寒假作业4—PTA编程总结1
查看>>
android自适应屏幕
查看>>
2019-北航面向对象-电梯作业总结
查看>>
SqlHelper
查看>>
初识算法、数据结构
查看>>