ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java字节流

2022-03-29 17:31:46  阅读:174  来源: 互联网

标签:Java 字节 写入 close 缓冲区 new 序列化


流的概念

流的概念:内存与存储设备之间数据传输的通道,数据借助流传输

流的分类

  • 按方向:以内存为参照
    • 输入流:将 存储设备 中的内容读入到 内存
    • 输出流:将 内存 中的内容写入到 存储设备
  • 按单位:
    • 字节流:以字节为单位,读写所有数据
    • 字符流:以字符为单位,读写文本数据
  • 按功能:
    • 节点流(底层流):具有实际传输数据的读写功能
    • 过滤流:在节点流的基础上增强功能,如缓冲流

字节流抽象类

  • 字节流的父类(抽象类):
    • InputStream:字节输入流
      • read()
      • close():节约资源
    • OutputStream:字节输出流
      • write()
      • close():节约资源

文件字节流

  • 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();

读取结果:为 fjkljk,默认读取的方法在读取结束时不会覆盖未读取的内容,需要对其进行限制:

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. 单个字节写入
//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. 字符串写入
//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,字节,写入,close,缓冲区,new,序列化
来源: https://www.cnblogs.com/chachan53/p/16072924.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有