在Java7中,InputStream被定义为一个抽象类,相应的,该类下的read()方法也是一个抽象方法,这也就意味着必须有一个类继承InputStream并且实现这个read方法。
  查阅Java7 API,我们可以看到,在InputStream中定义了三个重载的read()方法:

  但是在这三个方法中,只有参数列表为空的read方法定义为抽象方法,这也就意味着在直接继承自InputStream的所有子类中,必须重写这个方法。下面我们来看看这个方法的介绍:

  这里有两点需要注意:一是这个方法的返回值是int类型;二是在这个方法每次从数据源中读取一个byte并返回。很多初次接触Java的读者在看到这里时都会产生下面的疑问,就是这个方法读取的byte是如何以int的形式返回的。
  在计算机中,所有的文件都是以二进制的形式存储的,换句话说,每个文件不管是什么类型,在计算机中的形式都是一串0和1。而read()方法在读的时候是每次读取8个二进制位,这8个0或1就是我们所谓的一个byte(字节)。在这里通常容易产生的疑问就是将字节和字符混为一谈。无论在什么语言什么系统中,只要它符合当今世界对于计算机技术的主流定义,那么一个byte就是8个二进制位。而字符则不同,字符是与人为定义的编码规则相关的,一个字符的大小(也就是其所占的二进制位)是由编码规则决定的,比如在GBK编码中一个汉字用两个字节表示,而在utf-8中,一个汉字由3到4个字节表示。言归正传,既然一个byte表示8个二进制位,那么这8个二进制位就是一个0-255之间的十进制数字,实际上在Java中,byte就是一个0-255之间的整数,而将从文件中读取的二进制转化成十进制这一过程是由read()方法完成的。
  也就是说,read()这个方法完成的事情就是从数据源中读取8个二进制位,并将这8个0或1转换成十进制的整数,然后将其返回。
下面再来看read(byte[] b)这个方法,这个方法的介绍如下:
  这个方法使用一个byte的数组作为一个缓冲区,每次从数据源中读取和缓冲区大小(二进制位)相同的数据并将其存在缓冲区中。当然byte数组中存放的仍然是0-255的整数,将二进制转换为十进制这个过程仍然是read方法实现的。
  需要注意的是,虽然我们可以指定缓冲区的大小,但是read方法在读取数据的时候仍然是按照字节来读取的。在utf-8等变长编码中,一个复杂字符(比如汉字)所占字节往往大于1,并且长度往往是不固定的。(参照UTF-8编码规则)按照字节读取数据会将字符割裂,这就导致我们在使用read(byte[] b)方法读取文件时,虽然指定了缓冲区的大小,但是仍然会出现乱码。下面这段代码可以很好地解释这一点

public static void main(String[] args) throws IOException {// TODO Auto-generated method stubInputStream in = null;File f = new File("D:/test.txt");byte[] b = new byte[2];in = new FileInputStream(f);int i = 0;while ((i = in.read(b)) != -1) {String str = new String(b);System.out.print(str);}}
public static void main(String[] args) throws IOException {// TODO Auto-generated method stubInputStream in = null;File f = new File("D:/test.txt");byte[] b = new byte[2];in = new FileInputStream(f);int i = 0;while ((i = in.read(b)) != -1) {String str = new String(b);System.out.print(str);}}

文件如下(采用ANSI编码):

运行结果如下:

补充一点:在调用new String(byte[] b)这个构造方法时,java会根据传入的数据按照当前编码规则创建String,如果将编码方式改为GBK,则可以正常输出中文:

这是因为,GBK编码每个汉字占两个字节,缓冲区大小设为2就可以避免字符编码割裂的情况。

InputStream read()方法详解相关推荐

  1. 使用Java操作文本文件的方法详解

    使用Java操作文本文件的方法详解 摘要: 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而 ...

  2. android组件用法说明,Android第三方控件PhotoView使用方法详解

    Android第三方控件PhotoView使用方法详解 发布时间:2020-10-21 15:06:09 来源:脚本之家 阅读:74 作者:zhaihaohao1 PhotoView的简介: 这是一个 ...

  3. java 查询sql语句_java执行SQL语句实现查询的通用方法详解

    完成sql查询 并将查询结果放入vector容器,以便其他程序使用 /* * 执行sql查询语句 */ public static vector executequery(class clazz, s ...

  4. python统计csv行数_对Python 多线程统计所有csv文件的行数方法详解

    如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Th ...

  5. python修改文件内容_Python批量修改文本文件内容的方法详解

    这篇文章主要介绍了Python批量修改文本文件内容的方法的相关资料,需要的朋友可以参考下 Python批量替换文件内容,支持嵌套文件夹 import os path="./" fo ...

  6. python二维元组_python中读入二维csv格式的表格方法详解(以元组/列表形式表示)

    如何去读取一个没有表头的二维csv文件(如下图所示)? 并以元组的形式表现数据: ((1.0, 0.0, 3.0, 180.0), (2.0, 0.0, 2.0, 180.0), (3.0, 0.0, ...

  7. Spring JdbcTemplate方法详解

    2019独角兽企业重金招聘Python工程师标准>>> Spring JdbcTemplate方法详解 标签: springhsqldbjava存储数据库相关sql 2012-07- ...

  8. golang 解析php序列化,golang实现php里的serialize()和unserialize()序列和反序列方法详解...

    Golang 实现 PHP里的 serialize() . unserialize() 安装 go get -u github.com/techleeone/gophp/serialize 用法 pa ...

  9. ES5和ES6数组遍历方法详解

    ES5和ES6数组遍历方法详解 在ES5中常用的10种数组遍历方法: 1.原始的for循环语句 2.Array.prototype.forEach数组对象内置方法 3.Array.prototype. ...

  10. linux expect 输入密码,shell脚本无密码登录 expect的使用方法详解

    shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了. 从 ...

最新文章

  1. 重磅 !89页PPT揭秘AI产业爆发的拐点(附完整版下载)
  2. python turtle画彩虹-Python基础实例——绘制彩虹(turtle库的应用)
  3. Angular - 如何在页面加载后马上做初始化
  4. struts2下面如何同时使用servlet,就是如何实现struts与servlet共存
  5. codeforces B. Friends and Presents(二分+容斥)
  6. wps如何保存最终状态_如何使得打开word文件显示最终的修改状态
  7. tesseract 测试样例
  8. Linux内核信号量:二值信号量/互斥信号量,计数信号量,读写信号量
  9. [Android学习笔记]startActivityForResult和onActivityResult的使用
  10. javascript小技巧:同步服务器时间、同步倒计时
  11. 宋宝华Linux培训笔记-Linux系统开发与工具
  12. 智能风控建模全流程--看这篇就够了
  13. cass坡度土方计算案例_四面放坡且坡度不同的工程土方,CASS怎么算?
  14. 浪漫的七夕表白简单代码(简单的小代码)
  15. 微信小程序实现画布生成海报功能
  16. tex 表格内容换行_{Latex}{Tabular}文本超出表格自动换行
  17. 指纹识别的原理与优势
  18. 微信小程序多个倒计时
  19. html2canvas生成长图片时导致背景图渲染不全问题
  20. 点击“加入QQ群”链接打开电脑QQ扫码后发现登录地点不是本地

热门文章

  1. Sublime插件安装
  2. 《百年中国文学史》狂人日记
  3. QGIS编译(跨平台编译)之四十四:HDF5编译(Windows、Linux、MacOS环境下编译)
  4. Maven-settings配置
  5. 第一次写博客,给大家推荐几个C语言视频教程
  6. 20出头的人该怎么护肤?
  7. smtp 送信error原因
  8. 分析Android 搜狗输入法在微信和QQ中发送图片和表情
  9. Fedora安装MySQL
  10. 基于 Apache Druid 的实时分析平台在爱奇艺的实践