【Java】---IO:流、字节流

【Java】—IO:流、字节流



一、什么是流?

1.1 概念

流,指的是数据在硬盘内存之间的传输通道,是一种抽象概念。
从数据的交换方向上来分,流分为输入流输出流

输入流:数据从硬盘传输到内存。(硬盘 -> 内存)
输出流:数据从内存传输到硬盘。(内存 -> 硬盘)

需要处理异常:

  1. FileNotFoundException

FileNotFoundException

  1. IOException
    IOException

1.2 图例演示

数据的交换

1.3 分类

流的分类方式有许多种。

一、按 方向 分类:

  1. 输入流:将数据从存储设备读取到内存中的流。
  2. 输出流:将数据从内存写入到存储设备中的流。

二、按 数据处理单位 分类:

  1. 字节流:每次读取或写入数据的基本单位是字节的流。
  2. 字符流:每次读取或写入数据的基本单位是字符的流。

字节流和字符流的使用情况:
如果处理二进制文件,使用字节流
例:图像、音频、视频、class字节码文件。

如果处理文本数据,使用字符流
例:.txt、.java、.html。

如果想要按行读取数据,使用字符流

三、按 功能 分类:

  1. 节点流:具有实际传输数据能力的流。
  2. 过滤流: 在节点流的基础之上增强了功能的流。

二、文件字节流

2.1 概念

最基本的处理文件数据的字节流
文件字节流有两个类,分别代表输入和输出两种功能:FileInputStreamFileOutputStream
FileInputStream:文件字节输入流
FileOutputStream:文件字节输出流

FileOutputStream有两个构造方式:

  1. 一参构造:FileOutputStream(String path)
    特点:如果path指定的文件存在,之后写入时会覆盖此文件。

  2. 二参构造:FileOutputStream(String path,boolean append)
    特点:如果path指定的文件存在,之后写入时会将数据追加。

2.2 创建对象

第一种:

FileInputStream fis = new FileInputStream("D:\\文件测试\\1.txt");//构造方法可以接收字符串形式的地址
FileOutputStream fos = new FileOutputStream("D:\\文件测试\\1.txt");

第二种:

File file = new File("D:\\文件测试\\1.txt");
FileInputStream fis = new FileInputStream(file);//构造方法可以接收File类型
File file = new File("D:\\文件测试\\1.txt");
FileOutputStream fis = new FileOutputStream(file);

2.3 方法

2.3.1 read()

作用:读取单个字节,返回其ASCLL码,如果到达文件的末尾,返回-1
所需类型:FileInputStream
返回值类型:int
缺点:无法读取汉字,因为汉字至少占2字节,读取后会出现乱码。

磁盘中:
文件

代码演示:

File file = new File("D:\\文件测试\\1.txt");
FileInputStream fis = new FileInputStream(file);
int n = fis.read();//从文件中读取一个字节,并以byte形式输出
System.out.println((char)n);

运行结果:

H

2.3.2 read(byte[ ] buf)

作用:根据数组buf的长度,在其中添加数据,并返回添加数据的数量。如果没有数据,返回-1
所需类型:FileInputStream
返回值类型:int

磁盘中:
文件读取
代码演示:

File file = new File("D:\\文件测试\\1.txt");
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[20];
int len = fis.read(b);//将获取到的数据放入byte数组b中,并返回字节的数量
System.out.println("字节个数:");
System.out.println(len);
System.out.println("读取数据:");
System.out.println(new String(b).substring(0,len));//由于数据可能没有装满数组b,所以需要通过获取的长度len精确捕获

运行结果:

字节个数:
11
读取数据:
HelloWorld!

2.3.3 read(byte[ ] b,int offset,int len)

作用:从文件中读取字节,在文件的当前指针开始读len个字节,并将其存储在b数组中,存储的位置在b的offset下标开始,然后返回此次读取的数据的长度。如果文件中没有数据,返回-1。
所需类型:FileIputStream
返回值类型:int

磁盘中:
read重载

代码演示:

FileInputStream fis = new FileInputStream("D:\\文件测试\\1.txt");
byte[] b = new byte[100];
b[0] = 97;//埋下伏笔
int len = fis.read(b,1,30);//在文件中,从b数组下标1的位置赋值30个字节数据,并返回实际数据长度
System.out.println("数据长度:");
System.out.println(len);
System.out.println("数据:");
System.out.println(new String(b).substring(0,len / 3));//第一个数据为a,因为前面赋值过
//编码格式为utf-8,一个汉字占3个字节,所以除以3

运行结果:

数据长度:
18
数据:
a你好,世界!

2.3.4 write(byte[ ] b)

作用:将字节数组b中的内容写入文件,如果文件中有数据,则会全部覆盖
注意事项:在同一个线程中,写入文件中的数据会堆叠,不会覆盖,只会覆盖线程启动前的文件。
所需类型:FileOutputStream

磁盘中:
文件写入

代码演示:

File file = new File("D:\\文件测试\\1.txt");
FileOutputStream fop = new FileOutputStream(file);
FileInputStream fip = new FileInputStream(file);
byte[] b = new byte[100];
int len;

String s1 = "I am Tiger";
fop.write(s1.getBytes());//存储字母

len = fip.read(b);//将读取的数据存入b数组中
System.out.println(new String(b).substring(0,len));//显示读取的数据

String s2 = "你好世界";
fop.write(s2.getBytes());//存储汉字

len = fip.read(b);//将读取的数据存入b数组中
System.out.println(new String(b).substring(0,len));

fip.close();//养成好习惯,用完就关闭
fop.close();

运行结果:
运行结果

磁盘前后变化:
存入字母:
I am Tiger
数据覆盖了

存入汉字:
I am Tiger你好世界
数据堆叠了


三、对象流

3.1 概念

专门用于读取和写入对象的字节流。其中写入对象叫做对象序列化,读取对象叫做对象反序列化
对象序列化:将对象写入文件中。
对象反序列化:将对象从文件中读取出来。
若想实现序列化和反序列化,需要对象所在类实现接口:Serializable
以学生类为例:

public class Student implements Serializable{//只有实现Serializeble接口才能进行对象流操作。
//内部内容省略不写
}

对象字节流有两个类,分别代表输入和输出两种功能:ObjectInputStreamObjectOutputStream
ObjectInputStream:对象字节输入流
ObjectOutputStream:对象字节输出流

3.2 创建对象

第一种:

FileInputStream fis = new FileInputStream("D:\\文件测试\\1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
FileOutputStream fos = new FileOutputStream("D:\\文件测试\\1.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);

第二种:

File file = new File("D:\\文件测试\\1.txt");
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
File file = new File("D:\\文件测试\\1.txt");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);

第三种:

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\文件测试\\1.txt"));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\文件测试\\1.txt"));

3.3 方法

3.3.1 writeObject(Object obj)

作用:将对象obj存入文件中,对象所在类需要实现Serializable接口。
所需类型:ObjectOutputStream

代码演示:
Student类中:

public class Student implements Serializable{//Student类实现了Serializable接口
	String name;
	int age;
	String gender;

	Student(String name,int age,String gender){
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
}

main()中:

File file = new File("D:\\文件测试\\1.txt");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student stu1 = new Student("张三",18,"男");
oos.writeObject(stu1);
oos.flush();//将数据从缓存区中写入文件
fos.close();//用完了就关闭,养成好习惯
oos.close();

磁盘中:
写入对象

3.3.2 readObject(Object obj)

作用:将对象从文件中取出,取出的对象类型为Object,需要进行向下转型。对象所在类需要实现Serializable接口。
所需类型:ObjectInputStream

磁盘中:
写入对象

代码演示:
Student类中:

public class Student implements Serializable{//Student类实现了Serializable接口
	String name;
	int age;
	String gender;

	Student(String name,int age,String gender){
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	@Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

main()中:

File file = new File("D:\\文件测试\\1.txt");
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Student stu = (Student)ois.readObject();//从文件中读取对象
System.out.println(stu);

运行结果:

Student{name=‘张三’, age=18, gender=‘男’}


四、字节缓冲流

4.1 概念

比起文件字节流效率更加高,自带缓冲区,提高IO效率。
特点:

  1. 提高IO效率,减少访问磁盘的次数。
  2. 数据存储在缓冲区中,flush是将缓存区中的内容写入文件中,也可以直接close
    缓冲区

字节缓冲流有两个类,分别代表输入和输出两种功能:BufferedInputStreamBufferedOutputStream
BufferedInputStream:对象字节输入流
BufferedOutputStream:对象字节输出流

4.2 创建对象

第一种:

FileInputStream fis = new FileInputStream("D:\\文件测试\\1.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("D:\\文件测试\\1.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);

第二种:

File file = new File("D:\\文件测试\\1.txt");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
File file = new File("D:\\文件测试\\1.txt");
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);

第三种:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\文件测试\\1.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\文件测试\\1.txt"));

4.3 方法

4.3.1 write(byte b[ ])

作用:将数组b写入文件中。
所需类型:BufferedOutputStream

代码演示:

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\文件测试\\1.txt"));
String s = "Who are you";
bos.write(s.getBytes());//只能存储字符类型数据,所以需要转换
bos.flush();//此时数据在缓冲区中,使用flush方法将其真正写入文件
bos.close();//养成随手关门的好习惯

磁盘中:
存入文件

4.3.2 read()

作用:将文件读取出来
所需类型:BufferedInputStream

代码演示:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\文件测试\\1.txt"));
byte[] b = new byte[1024];//1KB
int len = bis.read(b);
System.out.println("数据长度:");
System.out.println(len);
System.out.println("读取的数据:");
System.out.println(new String(b).substring(0,len));//精确获取数据

运行结果:

数据长度:
11
读取的数据:
Who are you


总结

这篇文章总结了IO流中的字节流及其下属分类各流。

  • 31
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值