Java字节流read函数
问题引入
做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://chouxianyu.github.io/2018/09/22/Java字节流read函数/#more
欢迎转发和评论
Java字节流read函数的更多相关文章
- Java字节流实现文件夹的拷贝
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...
- java String.split()函数的用法分析
java String.split()函数的用法分析 栏目:Java基础 作者:admin 日期:2015-04-06 评论:0 点击: 3,195 次 在java.lang包中有String.spl ...
- 使用Java字节流拷贝文件
本文给出使用Java字节流实现文件拷贝的例子 package LearnJava; import java.io.*; public class FileTest { public static vo ...
- java 字节流和字符流的区别 转载
转载自:http://blog.csdn.net/cynhafa/article/details/6882061 java 字节流和字符流的区别 字节流与和字符流的使用非常相似,两者除了操作代码上的不 ...
- java 字节流和字符流的区别
转载自:http://blog.csdn.net/cynhafa/article/details/6882061 java 字节流和字符流的区别 字节流与和字符流的使用非常相似,两者除了操作代码上的不 ...
- C# 二进制字节流查找函数IndexOf
C# 二进制字节流查找函数IndexOf /// <summary> /// 报告指定的 System.Byte[] 在此实例中的第一个匹配项的索引. /// </summary&g ...
- Android使用JNI(从java调用本地函数)
当编写一个混合有本地C代码和Java的应用程序时,需要使用Java本地接口(JNI)作为连接桥梁.JNI作为一个软件层和API,允许使用本地代码调用Java对象的方法,同时也允许在Java方法中调用本 ...
- Java 字节流实现文件读写操作(InputStream-OutputStream)
Java 字节流实现文件读写操作(InputStream-OutputStream) 备注:字节流比字符流底层,但是效率底下. 字符流地址:http://pengyan5945.iteye.com/b ...
- 关于C++与Java中虚函数问题的读书笔记
之前一直用C++编程,对虚函数还是一些较为肤浅的理解.可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题. Java中的虚函数 以下是段别人的 ...
随机推荐
- 2019Java常见面试下
1.集合的作用是什么? 数据的传送增.删.改.查.constainsAll,可以存放不同类型的对象. 2.集合的通用方法有那些?通用方法是什么?(操作) 集合List的遍历方法有: Iterator: ...
- leetcode907 Sum of Subarray Minimums
思路: 对于每个数字A[i],使用单调栈找到A[i]作为最小值的所有区间数量,相乘并累加结果.时间复杂度O(n). 实现: class Solution { public: int sumSubarr ...
- 动态代理 aop切面实现事务管理
1.定义接口和实现 public interface UserService { public String getName(int id); public Integer getAge(int id ...
- hdu4813 01背包+前缀和
题意:\(A,B\)两人,有\(N\)个事件,每件发生的概率都为\(0.5\),若事件\(i\)发生,则\(B\)加\(v_i\)分数,若其不发生,则\(B\)不加分,给定一个概率\(P\),问至少需 ...
- Python中的幽灵—编码方式
首先要搞懂本地操作系统编码与系统编码的区别: 本地操作系统编码方式与操作系统有关,Linux默认编码方式为utf-8,Windows默认编码方式为gbk: 系统编码方式与编译器or解释器有关,Pyth ...
- 【第一季】CH05_FPGA设计Verilog基础(二)Enter a post title
[第一季]CH05_FPGA设计Verilog基础(二) 5.1状态机设计 状态机是许多数字系统的核心部件,是一类重要的时序逻辑电路.通常包括三个部分:一是下一个状态的逻辑电路,二是存储状态机当前状态 ...
- 第一章 MIZ701 VIVADO 搭建SOC最小系统HelloWorld
本章内容是MIZ701中的第五章,本来也是要过渡一下FPGA部分的,但是由于MIZ701没有单独提供PL部分的晶振时钟,时钟必须通过PS产生,所以本章内容作为Miz701的第一章内容.本章的目的是 ...
- 少儿编程Scratch第三讲:宇宙大战.枪战游戏
小朋友这周的表现还算不错.周末多数时间都由我陪(bi)着(zhe)做课本上的数学题,后来还学了英语.任重道远啊,语数外都还得加强,还远不到自己就能取得好成绩的阶段. 上周说好这周要做一个发射炮弹的游戏 ...
- shell习题第15题:看数字找规律
[题目要求] 请仔细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字 10 31 53 77 105 141... ... [核心要点] 计算两个数值之间的差值 [脚本] #!/bin/ ...
- IOC之MEF学习
MEF原理上很简单,找出有共同接口的导入.导出.然后找到把导出的实例化,赋给导入.说到底MEF就是找到合适的类实例化,把它交给导入.Export 特性可修饰类.字段.属性或方法,而 Import 特性 ...