一、FileInputStream 简介

1、概念

FileInputStream 是 Java 语言中抽象类 InputStream 用来具体实现类的创建对象。FileInputStream 流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等。

2、构造方法

1)通过打开与 File 类对象代表的实际文件的链接来创建 FileInputStream 流对象

public FileInputStream(File file) throws FileNotFoundException {String name = (file != null ? file.getPath() : null);SecurityManager security = System.getSecurityManager();if (security != null) {security.checkRead(name);}if (name == null) {throw new NullPointerException();}if (file.isInvalid()) {throw new FileNotFoundException("Invalid file path");} // 一系列合法性的判断fd = new FileDescriptor(); // 以下均是对成员变量的构造fd.attach(this);path = name;open(name); // 调用native方法打开文件
}

若 File 类对象的所代表的文件不存在、不是文件是目录、或者其他原因不能打开的话,则会抛出 FileNotFoundException 异常。

2)通过指定的字符串参数来创建File类对象,而后再与 File 对象所代表的实际路径建立链接创建 FileInputStream 流对象

public FileInputStream(String name) throws FileNotFoundException {this(name != null ? new File(name) : null);}

通过查看源码,发现该构造方法等于是在第一个构造方法的基础上进行延伸的,因此规则也和第一个构造方法一致:

3)通过 fdObj 文件描述符来作为参数,文件描述符是指与计算机系统中的文件的连接,前面两个方法的源码中最后都是利用文件描述符来建立连接的(了解)

public FileInputStream(FileDescriptor fdObj) {SecurityManager security = System.getSecurityManager();if (fdObj == null) {throw new NullPointerException();}if (security != null) {security.checkRead(fdObj);}fd = fdObj;path = null;fd.attach(this);
}

二、FileInputStream 常用方法

1、read() 从输入流中读取一个字节返回int型变量,若到达文件末尾,则返回-1

public int read() throws IOException

源码:

public class FileStream {public static void main(String[] args) {//建立文件对象File file = new File("D:test1.txt");try {//建立链接FileInputStream fileInputStream = new FileInputStream(file);int n = 0;StringBuffer sBuffer=new StringBuffer();while (n != -1){  //当n不等于-1,则代表未到末尾n = fileInputStream.read();//读取文件的一个字节(8个二进制位),并将其由二进制转成十进制的整数返回char by = (char) n; //转成字符sBuffer.append(by);}System.out.println(sBuffer.toString());} catch (FileNotFoundException e) {System.out.println("文件不存在或者文件不可读或者文件是目录");} catch (IOException e) {System.out.println("读取过程存在异常");} }
}

最后输出内容和 1.txt 内容一致是:123总结:从(来源)输入流中(读取的内容)读取数据的下一个字节到(去处)java程序内部中返回值为0到255的int类型的值,返回值为字符的ACSII值(如a就返回97,n就返回110).如果没有可用的字节,因为已经到达流的末尾, -1返回的值运行一次只读一个字节,所以经常与while((len = inputstream.read()) != -1)一起使用

2、read(byte[] b) 从输入流中读取 b.length 个字节到字节数组中,返回读入缓冲区的总字节数,若到达文件末尾,则返回-1

public int read(byte[] b) throws IOException

源码:

public int read(byte b[]) throws IOException {return readBytes(b, 0, b.length);
}

查看此方法源码,发现其本质是调用的其它方法 readBytes(b, 0, b.length);

总结:从(来源)输入流中(读取内容)读取的一定数量字节数,并将它们存储到(去处)缓冲区数组b中返回值为实际读取的字节数运行一次读取一定的数量的字节数.java会尽可能的读取b个字节,但也有可能读取少于b的字节数.至少读取一个字节第一个字节存储读入元素b[0],下一个b[1],等等。读取的字节数是最多等于b的长度。如果没有可用的字节,因为已经到达流的末尾, -1返回的值 如果b.length==0,则返回0

3、read(byte[] b,int off,int len) 从输入流中读取最多len个字节到字节数组中(从数组的off位置开始存储字节),当len为0时则返回0,如果len不为零,则该方法将阻塞,直到某些输入可用为止

public int read(byte[] b,int off,int len) throws IOException

源码:

public int read(byte b[], int off, int len) throws IOException {if (b == null) {throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) {throw new IndexOutOfBoundsException();} else if (len == 0) {return 0;}int c = read();if (c == -1) {return -1;}b[off] = (byte)c;int i = 1;try {for (; i < len ; i++) {c = read();if (c == -1) {break;}b[off + i] = (byte)c;}} catch (IOException ee) {}return i;}

总结:读取 len字节的数据从输入流到一个字节数组。试图读取多达 len字节,但可能读取到少于len字节。返回实际读取的字节数为整数。 第一个字节存储读入元素b[off],下一个b[off+1],等等。读取的字节数是最多等于len。k被读取的字节数,这些字节将存储在元素通过b[off+k-1]b[off],离开元素通过b[off+len-1]b[off+k]未受影响。

4、close() 关闭此输入流并释放与该流关联的所有系统资源---即释放与实际文件的连接

public void close() throws IOException

三、FileInputStream 常用 API 总结

1、为什么 read() 无参方法读取一个字节,返回的是一个 int 类型,而不是一个byte类型?

因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回 byte,有可能在读到中间的时候遇到 111111111(文件的底层按补码来存储的):

那么这 11111111 是 byte 类型的 -1,我们的程序是遇到 -1 就会停止不读了,后面的数据就读不到了,所以在读取的时候用 int 类型接收,如果 11111111 会在其前面补上 24 个 0 凑足 4 个字节,那么 byte 类型的 -1 就变成 int 类型的 255 了,这样可以保证整个数据读完,而结束标记的 -1 就是 int 类型。

2、三种 read 方法效率比较

查看三种 read 方法源码,其本质都是利用 for 循环对内容进行单字节的读取,但从代码形式看,使用 read(byte[] b) 较为直观和简便,因此项目中可以此方法为主进行数据读取。

知乎视频​www.zhihu.com

希望可以帮到大家~

fileinputstream_Java I/O 流之 FileInputStream相关推荐

  1. 字节流与字符流(FileInputStream类和FileOutputStream类)

    FileInputStream类和FileOutputStream类中,第一个类的源端和第二个类的目的端都是磁盘文件,它们的构造方法允许通过文件的路径名来构造相应的流.例如: FileInputSte ...

  2. Io流的FileInputStream和FileOutputStream的读取和写入

    一 .如何读写文件 通过流来读取文件.流是指一连串流动的字符,是以先进先出的方式发送信息通道. 二.Java流的分类 按流的流向来分 1.输出流 Outputstream 和writer作为基类 2. ...

  3. java中文件流close_Java FileInputStream close()方法与示例

    FileInputStream类close()方法close()方法在java.io包中可用. close()方法用于关闭此FileInputStream并释放与此流链接的所有系统资源. close( ...

  4. java文件流读取异常_Java IO流的FileInputStream读取文件的问题,不同写法输出不一样...

    利用FileInputStream的read()方法读取文件时,读出的数据强制转换时用不同的写法,在控制台得出不同的显示. 出问题的写法: 正确输出的写法: 以下为两种输出,错误输出是输出一串数字,正 ...

  5. java fileinputstream_java – 需要将AssetInputStream转换为FileInputStream

    我已经实现了一个在我的计算机上运行的数据结构,现在我正在尝试将其移植到我的 Android应用程序中.我打开一个原始.dat资源并获取一个InputStream但我需要获取一个FileInputStr ...

  6. Java IO 字节流与字符流 (三)

    概述 IO流用来处理设备之间的数据传输 Java对数据的操作时通过流的方式 Java用于操作流的对象都在IO包中 流按操作的数据分为:字节流和字符流 流按流向不同分为:输入流和输出流 IO流常用基类 ...

  7. 08 - JavaSE之IO流

    IO流 JAVA流式输入输出原理:可以想象成一根管道怼到文件上,另一端是我们程序,然后流的输入输出都是按照程序本身作为第一人称说明的.比如 input,对于我们程序来说就是有数据输入我们程序,outp ...

  8. java流实例_java流汇总以及使用实例

    流 一.基本概念 Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络) 读入到内存中,形成了流,然后将这些流还可以写到另外的目的 ...

  9. Java文件流应用:剪切文件

    剪切的实际操作是: 第一步,先复制文件到指定位置, 第二步,删除原文件,这样就实现了剪切 与复制文件相比,多了一步删除文件 注意:删除文件必须在流关闭后,才能删除,否则,删除不了. 实例代码 pack ...

最新文章

  1. Java学习总结:44(文件复制案例)
  2. 20、30、40岁年轻人,2020年的建议 转载
  3. DC课程笔记-数字逻辑综合工具-DC Environment Attributes
  4. 成功解决TypeError: __init__() got an unexpected keyword argument 'n_iterations'
  5. 删除隐藏版本信息 版本回退_Git系列之-分布式版本控制Git详解
  6. 5 Android数据存储 任务二 应用程序数据文件夹里的文件读写 ,
  7. python web开发-flask中日志的使用
  8. 团队作业—预则立他山之石
  9. 【Leetocde | 10 】54. 螺旋矩阵
  10. 生成式模型与判别式模型—大厂笔试汇总
  11. 中国女排代言作业帮直播课,作业帮累计用户已超8亿
  12. Async/await 和 Promises 区别
  13. POJ2083-Fractal
  14. mtk最新刷机平台SP_Flash_Tool_v6.2208_Win
  15. 玻尔原子模型中各轨道半径、轨道能量公式推导
  16. 2019年年终总结及明年的期望
  17. python append 字典_Python3中使用append添加字典元素出现问题
  18. torch.manual_seed()及其作用
  19. RK3568关于RK808的定时开关机
  20. vue+elementui实现非常好看的博客、网站首页,网站模板

热门文章

  1. apiCloud中的API对象
  2. Spring的@Scheduled任务调度
  3. C# DateTime简单的定时器用法
  4. #define typedef 区别
  5. C语言 二维数组做函数参数的几种情况
  6. 如何通过对方IP地址查对方的MAC
  7. NHibernate之旅(4):探索查询之条件查询(Criteria Query)
  8. c++ STL 工程实践的15条建议
  9. 你增长的年龄,是因为丢掉了快乐吗?
  10. 一个深入学习Linux/C/C++的原创技术号