文章目录

  • 1.什么是InputStream(输入流)?
  • 2.JDK中对InputStream的定义
  • 2.1 使用FileInputStream读取文件
  • 2.1.1 read() 使用实例
  • 2.1.2 read(byte[] b)使用实例
  • 2.1.3 read(byte[] b , int off,int len)
  • 2.2 其他方法学习
  • 2.2.1 skip(long n) 跳过源中指定字节数进行读取
  • 2.2.2 available() 预估剩余未读取的字节数量
  • 2.2.3 mark(int readlimit) 标记重读点,并设置重读点失效条件(和缓冲区相关)
  • 2.2.4 reset() 将流的游标重置为重读点
  • 2.2.5 markSupported() 钩子方法,供实现类使用,如果实现类支持mark,reset将其实现返回true


1.什么是InputStream(输入流)?

在JavaAPI中,我们可以从字节序列来源地读入一个字节序列的对象称为输入流。字节序列的来源地可以是文件,也可以是网络,还可以是内存块等等。
输入流根据每次读取的字节数量的不同分为字节输入流和字符输入流。 字节输入流每次都是读取一个字节的,而字符输入流每次读入都是根据基于两字节的字符为单位读取的。

2.JDK中对InputStream的定义

在JDK中,InputStream是一个抽象类,其主要方法定义如下:

方法定义

返回值描述

方法描述

abstract int read()

返回的是读入的字节asc码(-1~225)

当读取完毕时,返回-1

int read(byte b[])

将源中的字节信息填充到b中

当填充完毕时,返回实际填充数

int read(byte b[],int off,int len)

将b中指定位置填充源中的字节

当填充完毕时,返回实际填充数

这个类的主要能力定义就是从文件或网络或某处读取数据到程序中。这个某处我们称之为,而根据这个源的不同实现出了不同的具体的实现类来让我们方便使用。

2.1 使用FileInputStream读取文件

下面使用它的一个实现类FileInputStream读取文件
FileInputStream顾名思义,它是源为文件的字节输入流。

2.1.1 read() 使用实例

/**
 * FileInputStream实例
 * @throws IOException
 */
public static void fileInputStreamStudy() throws IOException {
    InputStream inputStream = new FileInputStream("麻子.txt");
    int n;
    while ((n=inputStream.read())!=-1){
        System.out.print((char)n);
    }
}

上面的测试,每次读取都是读取的一个字节,所以后面的中文是可能无法正确显示的,因为中文为两个字节一组:

InputStream Java 重新读取 java读取inputstream内容_System

2.1.2 read(byte[] b)使用实例

public static void readByteStudy() throws IOException {
    InputStream inputStream = new FileInputStream("麻子.txt");
    byte[] a = new byte[1000];
    System.out.println(inputStream.read(a));
    for (byte n:a){
        System.out.print((char)n);
    }
}

InputStream Java 重新读取 java读取inputstream内容_java_02

2.1.3 read(byte[] b , int off,int len)

public static void readByteLengthStudy() throws IOException {
    InputStream inputStream = new FileInputStream("麻子.txt");
    byte[] a = new byte[1000];
    System.out.println(inputStream.read(a,100,100));
    for (byte n:a){
        System.out.print((char)n);
    }
}

InputStream Java 重新读取 java读取inputstream内容_输入流_03

2.2 其他方法学习

2.2.1 skip(long n) 跳过源中指定字节数进行读取

/**
 * skip可以跳过源中一定数量的字节
 * @throws IOException
 */
public static void skipStudy() throws IOException {
    InputStream inputStream = new FileInputStream("麻子.txt");
    System.out.println(inputStream.skip(100));
    int n;
    while ((n=inputStream.read())!=-1){
        System.out.println(inputStream.available());
        System.out.print((char)n);
    }
}

InputStream Java 重新读取 java读取inputstream内容_System_04

2.2.2 available() 预估剩余未读取的字节数量

/**
 * available可以预估剩余未读取的字节估计数
 * @throws IOException
 */
public static void availableStudy() throws IOException {
    InputStream inputStream = new FileInputStream("麻子.txt");
    int n;
    while ((n=inputStream.read())!=-1){
        System.out.println(inputStream.available());
        System.out.print((char)n);
    }
}

InputStream Java 重新读取 java读取inputstream内容_java_05

2.2.3 mark(int readlimit) 标记重读点,并设置重读点失效条件(和缓冲区相关)

2.2.4 reset() 将流的游标重置为重读点

/**
 * mark在JAVA中的实现是和缓冲区相关的。只要缓冲区够大,mark后读取的数据没有超出缓冲区的大小,mark标记就不会失效。
 * 如果不够大,mark后又读取了大量的数据,导致缓冲区更新,原来标记的位置自然找不到了。
 * 因此,mark后读取多少字节才失效,并不完全由readlimit参数确定,也和BufferedInputStream类的缓冲区大小有关。
 * 如果BufferedInputStream类的缓冲区大小大于readlimit,在mark以后只有读取超过缓冲区大小的数据,mark标记才会失效。
 * @throws IOException
 */
public static void markStudy() throws IOException {
    InputStream inputStream = new BufferedInputStream(new FileInputStream("麻子.txt"));
    int n;
    while ((n=inputStream.read())!=-1){
        if(n==173) inputStream.mark(50);//这里的readLimit和实际情况相关
        System.out.println(n);
    }
    inputStream.reset();
    System.out.println("调用reset 重新读取");
    while ((n=inputStream.read())!=-1){
        System.out.println(n);
    }
}

InputStream Java 重新读取 java读取inputstream内容_System_06

2.2.5 markSupported() 钩子方法,供实现类使用,如果实现类支持mark,reset将其实现返回true

InputStream默认为false

public boolean markSupported() {
    return false;
}