Java字节流
2022/3/29 17:56:30
本文主要是介绍Java字节流,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
流的概念
流的概念:内存与存储设备之间数据传输的通道,数据借助流传输
流的分类
- 按方向:以内存为参照
- 输入流:将 存储设备 中的内容读入到 内存 中
- 输出流:将 内存 中的内容写入到 存储设备 中
- 按单位:
- 字节流:以字节为单位,读写所有数据
- 字符流:以字符为单位,读写文本数据
- 按功能:
- 节点流(底层流):具有实际传输数据的读写功能
- 过滤流:在节点流的基础上增强功能,如缓冲流
字节流抽象类
- 字节流的父类(抽象类):
- InputStream:字节输入流
read()
close()
:节约资源
- OutputStream:字节输出流
write()
close()
:节约资源
- InputStream:字节输入流
文件字节流
-
FileInputStream:
read(byte[] b)
:从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1
//1 创建 FileInputStream,并指定路径 FileInputStream fis = new FileInputStream("F:\\a.txt"); //2 读文件 //读一个字节 int data = 0; while ((data = fis.read()) != -1) { System.out.print((char) data); } //3.关闭 fis.close();
使用byte[]读取多个字节
FileInputStream fis = new FileInputStream("F:\\a.txt"); byte[] b = new byte[3]; int count = fis.read(b);//read()范围值为读取字节的个数 System.out.println(new String(b)); System.out.println(count); int count2 = fis.read(b); System.out.println(new String(b)); System.out.println(count2); fis.close();
读取结果:为 fjk
和 ljk
,默认读取的方法在读取结束时不会覆盖未读取的内容,需要对其进行限制:
int count5 = fis.read(b); System.out.println(new String(b,0,count5));//l System.out.println(count5);//1
使用循环读取:
FileInputStream fis = new FileInputStream("F:\\a.txt"); byte[] b = new byte[3]; int count = 0; while((count = fis.read(b))!= -1){ System.out.println(new String(b,0,count)); } fis.close();
- FileOutputStream:
write(byte[] b)
:一次写多个字节,将b数组中所有字节,写入输出流- 覆盖:默认写入时对原文件进行覆盖,如果不想进行覆盖,在读取文件时设置为
true
FileOutputStream fileOutputStream = new FileOutputStream("F:\\b.txt",true);
- 单个字节写入
//1 创建文件输出流对象 FileOutputStream fileOutputStream = new FileOutputStream("F:\\b.txt"); //2. 写入文件 fileOutputStream.write(97); fileOutputStream.write('c'); fileOutputStream.write('s'); //3. 关闭 fileOutputStream.close(); System.out.println("执行完毕");
- 字符串写入
//1 创建文件输出流对象 FileOutputStream fileOutputStream = new FileOutputStream("F:\\b.txt"); //2. 写入文件 String s = "Hello,world"; fileOutputStream.write(s.getBytes());//执行写入操作的时候覆盖源文件 //3. 关闭 fileOutputStream.close(); System.out.println("执行完毕");
复制文件
字节流可以复制任何文件
//1. 创建流 //文件字节输入流 FileInputStream fileInputStream = new FileInputStream("F:\\wall.jpg"); //文件字节输出流 FileOutputStream fileOutputStream = new FileOutputStream("F:\\1.jpg"); //2. 边读边写 byte[] b = new byte[1024]; int count = 0; while ((count=fileInputStream.read(b))!=-1){ fileOutputStream.write(b,0,count); } //3. 关闭 fileInputStream.close(); fileOutputStream.close(); System.out.println("复制完毕");
字节缓冲流
- 缓冲流:
- BufferedInputStream
- BufferedOutputStream
- 作用:
- 提高IO效率,减少访问磁盘的次数
- 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close
缓冲流读取文件
//1. 创建BufferedInputStream //把字节流传入缓冲流 FileInputStream fileInputStream = new FileInputStream("F:\\a.txt"); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); //2. 读取 //读取到缓冲区,然后再读取到文件中,缓冲区大小维8192 int data = 0; while((data=bufferedInputStream.read())!=-1){ System.out.print((char)data); } //3.关闭缓冲区 bufferedInputStream.close();
创建缓冲区(与前文的字符串读取相同,byte[]起到缓冲区作用)
//1. 创建BufferedInputStream //把字节流传入缓冲流 FileInputStream fileInputStream = new FileInputStream("F:\\buffer.txt"); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); //2. 读取 //自己创建缓冲区 byte[] b = new byte[1024]; int count = 0; while((count = fileInputStream.read(b))!=-1){ System.out.println(new String(b,0,count)); } //3.关闭缓冲区 bufferedInputStream.close();
缓冲流写入文件
- 在使用缓冲区写入文件时,需要进行
flush
刷新才能将缓冲区的内容写入硬盘中 - 当缓冲区写满时,会自动调用
flush
进行写入 - 在
close
缓冲流时,会调用flush
进行把缓冲区的内容写入硬盘中 - 主动进行
flush
操作可以提高效率
//1.创建字节输出缓冲流 FileOutputStream fileOutputStream = new FileOutputStream("F:\\buffer.txt"); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //2.写入文件 for (int i = 0; i < 9; i++) { //仅写入缓冲区中,没有写入硬盘中,缓冲区满了会自动调用flush bufferedOutputStream.write("hello,world!\r\n".getBytes()); //刷新到硬盘中,提高效率 bufferedOutputStream.flush(); } //3.close(内部调用flush) //即使不进行刷新,关闭缓冲区时也会写入到硬盘中 bufferedOutputStream.close();
对象流
- 对象流:
- ObjectOutputStream
- ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象的功能
- readObject():从流中读取一个对象(反序列化)
- writeObject(Object obj):向流中写入一个对象(序列化)
序列化
序列化是将数据类型和类进行写入,要序列化类必须实现 Serializable
接口
- 类的定义:
public class Student implements Serializable{}
- 类的序列化
//1.创建对象流 FileOutputStream fileOutputStream = new FileOutputStream("F:\\stu.bin"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); //2.序列化(写入操作) Student stu1 = new Student("小王",29); objectOutputStream.writeObject(stu1);//需要进行序列化,需要使类实现序列化的接口 //3.关闭 objectOutputStream.close(); System.out.println("序列化完毕");
反序列化
反序列化:读取文件,再重构成对象
一个对象仅能反序列化一次
//1. 创建对象流 FileInputStream fileInputStream = new FileInputStream("F:\\stu.bin"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); //2. 读取文件(反序列化) Student stu = (Student)objectInputStream.readObject(); //如果读取两次会出现异常,每个对象反序列化仅能进行一次 // Student stu2 = (Student)objectInputStream.readObject(); System.out.println(stu.toString()); //3. 关闭 objectInputStream.close();
注意事项
序列化:
- 序列化类必须要实现Serializable接口
- 序列化类中的对象属性,即引用类型字段也要实现Seralizable接口
- 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
private static final long serialVersionUID = xxxL;
- 使用
transient
(瞬间的)修饰属性,使属性不被序列化 - 静态属性不能序列化
- 序列化多个对象,可以借助集合实现
序列化:
//序列化多个对象 Student stu1 = new Student("小王",29); Student stu2 = new Student("林",12); ArrayList<Student> list = new ArrayList<>(); list.add(stu1); list.add(stu2); objectOutputStream.writeObject(list);//需要进行序列化,需要使类实现序列化的接口
反序列化:
//反序列化 ArrayList<Student> list = (ArrayList<Student>) objectInputStream.readObject(); System.out.println(list.toString());
这篇关于Java字节流的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27消息中间件底层原理资料详解
- 2024-11-27RocketMQ底层原理资料详解:新手入门教程
- 2024-11-27MQ底层原理资料详解:新手入门教程
- 2024-11-27MQ项目开发资料入门教程
- 2024-11-27RocketMQ源码资料详解:新手入门教程
- 2024-11-27本地多文件上传简易教程
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器