2023年2月

本课程主要如何利用Java类库中提供的InputStream类,并基于Java编程实现文件信息的读取,以及三个read()方法与OutputStream类中三个write()方法的操作区别形式



OutputStream抽象类对应的另外一个操作类就属于java.io.InputStream类,这个类可以基于字节的方式实现指定输入流数据的读取操作,此类的定义如下:



public abstract class InputStream extends Object implements Closeable



InputStream类也同样实现了Closeable接口(是在JDK后续版本中添加的),而对于InputStream类来讲其提供有如下的数据读取的处理方法。



OutputStream类中提供有三个write()方法,反过来在InputStream类中又提供有三个read()方法,无论从方法的名称上以及参数的类型及个数上都是非常对称的,下面通过一些具体的图示来分析这三个读取数据操作方法的区别所在。



范例:通过InputStream实现数据的读取



package com.yootk.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class YootkDemo { // 李兴华编程训练营:yootk
public static void main(String[] args) throws Exception {
File file = 
new File("H:" + File.separator "muyan" + File.separator "vip" + File.separator "yootk.txt");
if (file.exists()) { // 文件存在
try (InputStream input = new FileInputStream(file)) {
byte data[] = new byte[1024]; // 开辟1K的空间进行读取
int len = input.read(data); // 读取数据到字节数组并返回读取个数
System.out.println("读取到的数据内容【new String(data, 0, len) + "");
catch (Exception e) {}
}
}
}



此时的程序已经实现了整个数据内容的读取,但是这里面还会存在有另外一个问题,如果说此时要读取的内容很大,但是所开辟的数组空间很小,这个时候肯定无法一次性进行数据的读取,那么就需要重复多次读取,而如果文件已经读取到底部的时候,调用read()方法返回的内容就是“-1”(不再是读取到的字节个数了)。



范例:执行数据的多次读取



package com.yootk.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class YootkDemo { // 李兴华编程训练营:yootk
public static void main(String[] args) throws Exception {
StringBuffer buffer = 
new StringBuffer() ; // 保存读取到的内容
File file = new File("H:" + File.separator "muyan" + File.separator "vip" + File.separator "yootk.txt");
if (file.exists()) { // 文件存在
try (InputStream input = new FileInputStream(file)) {
byte data[] = new byte[8]; // 开辟1K的空间进行读取
int len = ;// 保存数据读取的个数
do {
len = input.read(data); 
// 读取数据到字节数组并返回读取个数
if (len != -1) {
buffer.append(
new String(data, 0, len)); // 每次读取到的内容保存在缓冲流中
}
while (len != -1) ; // 没有读取到底
System.out.println("读取到的数据内容【+ buffer + "");
catch (Exception e) {
e.printStackTrace();
}
}
}
}



以上的程序由于一次性的读取不可能将所有的内容全部读取完成,所以采用的方式就是进行部分读取的处理,而在进行部分读取的时候又需要将每一次读取到的内容保存在StringBuffer之中,但是在保存的时候必须保证有内容读取的时候(len != -1)才可以实现数据的添加,只不过这上面的代码有些过于繁琐了,而实际的项目开发过程之中,对于此类的操作一般采用的都是while循环的结构方式。



byte data[] = new byte[8]; // 开辟1K的空间进行读取
int len = ;// 保存数据读取的个数
// 第一个表达式:input.read(data),将输入流的数据读取到字节数组之中
// 第二个表达式:len = input.read(data),将读取到的数据长度赋值给len变量
// 第三个表达式:(len = input.read(data)) != -1,判断len的内容是否不为-1
while ((len = input.read(data)) != -1) {
buffer.append(new String(data, 0, len));
}



相比较之前学习到的do…while处理结构,使用while循环的模式代码会更加的简洁,而这种读取模式是在以后进行IO操作中最为常见的原始方案。