字节输入流 InputStream
java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。
public void close():关闭此输入流并释放与此流相关联的任何系统资源。public abstract int read(): 从输入流读取数据的下一个字节。public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
注意:
close方法,当完成流的操作时,必须调用此方法,释放系统资源。
作用:把硬盘文件中的数据,读取到内存中使用
写入数据的原理:java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据写入到文件中
字节输入使用步骤:
- 创建一个FileInputStream对象,构造方法中绑定要读取的数据
- 使用FileInputStream对象中的read方法,读取文件
- 释放资源,提高程序的效率
2.5 FileInputStream类
java.io.FileInputStream 类是文件输入流,从文件中读取字节。
构造方法
FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
构造方法的作用:
- 会创建一个FileInputStream对象
- 会把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");
}
}
读取字节数据
- 读取字节:
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
注意:
- 虽然读取了一个字节,但是会自动提升为int类型。
- 循环语句记得写对!!!!
- 流操作完毕后,必须释放系统资源,调用close方法,千万记得。
- 使用字节数组读取:
read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1,起到缓冲作用。 - 代码使用演示:
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操作次数,从而提高了读写的效率,建议开发中使用。