字节输入流 InputStream

196 阅读4分钟

字节输入流 InputStream

java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

  • public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
  • public abstract int read(): 从输入流读取数据的下一个字节。
  • public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

注意:

  1. close方法,当完成流的操作时,必须调用此方法,释放系统资源。

  2. 作用:把硬盘文件中的数据,读取到内存中使用

  3. 写入数据的原理:java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据写入到文件中

  4. 字节输入使用步骤:

    • 创建一个FileInputStream对象,构造方法中绑定要读取的数据
    • 使用FileInputStream对象中的read方法,读取文件
    • 释放资源,提高程序的效率

2.5 FileInputStream类

java.io.FileInputStream 类是文件输入流,从文件中读取字节。

构造方法

  • FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  • FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

构造方法的作用:

  1. 会创建一个FileInputStream对象
  2. 会把FileInputStream对象指定构造方法中要读取的文件

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException

  • 构造举例,代码如下:
public class FileInputStreamConstructor throws IOException{
    public static void main(String[] args) {
   	 	// 使用File对象创建流对象
        File file = new File("a.txt");
        FileInputStream fos = new FileInputStream(file);
      
        // 使用文件名称创建流对象
        FileInputStream fos = new FileInputStream("b.txt");
    }
}

读取字节数据

  1. 读取字节read方法,每次可以读取一个字节的数据,自动提升为int类型,读取到文件末尾,返回-1,代码使用演示:
public class FISRead {
    public static void main(String[] args) throws IOException{
      	// 使用文件名称创建流对象
       	FileInputStream fis = new FileInputStream("D:\笔记\字节输出流测试文件夹\1.txt");
        // 1.txt中的内容 abc123456
      	// 读取数据,返回一个字节
        int read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
      	// 读取到末尾,返回-1
       	read = fis.read();
        System.out.println( read);
		// 关闭资源
        fis.close();
    }
}
输出结果:
a
b
c
1
2
3
4
5
6
-1

循环改进读取方式,代码使用演示:

public class FISRead {
    public static void main(String[] args) throws IOException{
      	// 使用文件名称创建流对象
       	FileInputStream fis = new FileInputStream("D:\笔记\字节输出流测试文件夹\1.txt");
        // 1.txt中的内容 abc123456
      	// 定义变量,保存数据
        int b = 0 ;
        // 循环读取
        while ((b = fis.read())!=-1) {
            System.out.println((char)b);
        }
        
        /*
        错误的循环语句写法://因为 read方法读一次,指针会自己跳到下一个字节
            while( fis.read()!=-1 ){
            System.out.print(char(fis.read())+" ");//b 1 3 5 -1
        
        */
        
		// 关闭资源
        fis.close();
    }
}
输出结果:
a
b
c
1
2
3    
4    
5
6

注意:

  1. 虽然读取了一个字节,但是会自动提升为int类型
  2. 循环语句记得写对!!!!
  3. 流操作完毕后,必须释放系统资源,调用close方法,千万记得。
  1. 使用字节数组读取read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1 ,起到缓冲作用。
  2. 代码使用演示:
public class FISRead {
    public static void main(String[] args) throws IOException{
      	// 使用文件名称创建流对象.
       	FileInputStream fis = new FileInputStream("D:\笔记\字节输出流测试文件夹\\3.txt"); // 文件中为abcde
      	// 3.txt 文件中的数据:abcde
        // 定义变量,作为有效个数
        int len ;
        // 定义字节数组,作为装字节数据的容器   
        byte[] b = new byte[2];
        // 循环读取
        while (( len= fis.read(b))!=-1) {
           	// 每次读取后,把数组变成字符串打印
            System.out.println(new String(b));
        }
		// 关闭资源
        fis.close();
    }
}

输出结果:
ab
cd
ed

错误数据d,是由于最后一次读取时,只读取一个字节e,数组中,上次读取的数据没有被完全替换,所以要通过len ,获取有效的字节,代码使用演示:

public class FISRead {
    public static void main(String[] args) throws IOException{
      	// 使用文件名称创建流对象.
       	FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde
      	// 定义变量,作为有效个数
        int len ;
        // 定义字节数组,作为装字节数据的容器   
        byte[] b = new byte[2];
        // 循环读取
        while (( len= fis.read(b))!=-1) {
           	// 每次读取后,把数组的有效字节部分,变成字符串打印
            System.out.println(new String(b,0,len));//  len 每次读取的有效字节个数
        }
		// 关闭资源
        fis.close();
    }
}

输出结果:
ab
cd
e

注意:

使用数组读取,每次读取多个字节,减少了系统间的IO操作次数,从而提高了读写的效率,建议开发中使用。