76 javaIO_2 _字节流

Java IO流详解

字节流

字节流的父类(抽象类):

java.lang.Object ---> java.io.InputStream
java.lang.Object ---> java.io.OutputStream
  • InputStream:字节输入流

    ​ 此抽象类是表示字节输入流的所有类的超类。

    ​ 部分方法:

    ​ public int read(){}

    ​ public int read(byte[] b){}

    ​ public int read(byte[] b, int off, int len){}

  • OutputStream:字节输入流

    ​ 此抽象类是表示输出字节流的所有类的超类。

    ​ 部分方法:

    ​ public int write(){}

    ​ public int write(byte[] b){}

    ​ public int write(byte[] b, int off, int len){}

字节流抽象类的子类:文件字节流

java.io.InputStream ---> java.io.FileInputStream
java.io.OutputStream ---> java.io.FileOutputStream
  1. FileInputStream: 从文件系统中的某个文件中获得输入字节

    • public int read() // 从此输入流中读取一个数据字节。如果达到文件的尾部,则返回-1。
    • public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
    • public int read(byte[] b, int off, int len) //从此输入流中将最多 len个字节的数据读入一个 byte 数组中。
  2. FileOutputStream:

    • public void write(int b) // 将指定字节写入此文件输出流。
    • public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
    • public void write(byte[] b, int off, int len) // 将指定 byte 数组中从偏移量 off 开始的 len个字节写入此文件输出流。

FileInputStream案例代码:

package com.wlw.io;

import java.io.FileInputStream;
import java.util.Arrays;

/**
 * 演示FileInputStream的使用
 * 文件字节输入流
 */
public class FileInputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建文件字节输入流,通过路径名来指定文件(也可以是File file)
        FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\aaa.txt");

        //2.读取文件
        //2.1 用read()一个字节一个字节读
        /*
        int data = 0;//read()返回的是数据的ASCII码,如果达到文件的尾部,则返回-1。
        while ((data = fis.read())!= -1){//读完数据
            System.out.print((char) data); //转成字符输出
        }
        */
        //2.2用read(byte[] b)读取,一次读取多个字节
        // 将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
        byte[] buf = new byte[1024];//用来接收数据
        int count = 0; //存放读到的字节数
        while ((count = fis.read(buf)) != -1){//读完数据
            System.out.println(new String(buf,0,count));
        }
        
        //3.关闭流
        fis.close();
        System.out.println();
        System.out.println("执行完毕");
    }
}

FileOutputStream案例代码:

package com.wlw.io;

import java.io.FileOutputStream;

/**
 * 演示FileOutputStream的使用
 * 文件字节输出流
 */
public class FileOutputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建文件字节输出流,可以通过路径来指定(没有的话会自动创建),(也可以是File file)
        FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\bbb.txt");
        //上面的创建方式在写入时,会把原文件覆盖,下面的创建方式是添加
        //FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\bbb.txt",true);

        //2.写入
        //2.1 write(int b)  // 将指定字节写入此文件输出流
        /*
        fos.write(97);//a
        fos.write('b');
        fos.write('c');
        */
        //2.2write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
        String str = "HelloWorld";
        fos.write(str.getBytes());

        //3.关闭流
        fos.close();

    }
}

文件字节流复制文件:

package com.wlw.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * 使用文件字节流实现文件的复制
 */
public class FileCopyDemo {
    public static void main(String[] args) throws Exception{
        //1.创建流
        //1.1创建文件输入流
        FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\复制文件.png");
        //1.2创建文件输出流
        FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\复制文件1.png");

        //2.复制(一边读,一边写)
        byte[] bytes = new byte[1024];//存储数据
        int count = 0;//存放读取的字节数
        while ((count = fis.read(bytes)) != -1){//读完数据
            fos.write(bytes,0,count);//不多写,读多少 写多少
        }

        //关闭流
        fis.close();
        fos.close();
        System.out.println("复制完毕");
    }
}

过滤流的子类:字节缓冲流

java.io.InputStream --> java.io.FilterInputStream---> java.io.BufferedInputStream
java.io.OutputStream --> java.io.FilterOutputStream---> java.io.BufferedOutputStream

缓冲流: BufferedInputStream/ BufferedOutputStream

  • 提高I0效率,减少访问磁盘的次数;

  • 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。

  1. BufferedInputStream:为另一个输入流添加一些功能,为其他流增强功能,需要传入其他流

    • 构造方法:BufferedInputStream (InputStream in)
  2. BufferedOutputStream:该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

    • 构造方法:BufferedPutputStream (OutputStream out)
    • void flush() //刷新此缓冲的输出流。

BufferedInputStream案例代码:

package com.wlw.io;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

/**
 * 使用字节缓冲流读取
 * BufferedInputStream
 * 可以提高读取的效率
 */
public class BufferedInputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建BufferInputStream,需要往里面传入一个节点流
        FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);

        //2.读取,字节缓冲流里面有个8k的缓冲区,先把数据读到缓冲区里
        /*
        int data = 0;
        while ((data = bis.read()) != -1){//读完会返回-1
            System.out.print((char)data);
        }
        */
        //自己写一个缓冲区
        byte[] buf = new byte[1024];
        int count = 0;
        while ((count = bis.read(buf)) != -1){
            System.out.println(new String(buf,0,count));
        }

        //3.关闭流
        bis.close();//它会帮我们关闭fis
    }
}

BufferedOutputStream案例代码:

package com.wlw.io;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

/**
 * 使用字节缓冲流写入文件
 * BufferedOutputStream
 */
public class BufferOutputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建字节缓冲流,需要往里面传入一个节点流
        FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\bufferOut.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //2.写入文件
        for (int i = 0; i < 10; i++) {
            bos.write("HelloWorld\r\n".getBytes());//写入到8k的缓冲区中,还没有写入到文件中
            bos.flush();//将数据写入到存储设备(硬盘,我们指定的文件中)
        }

        //3.关闭流
        bos.close();//此方法内部也会调用flush()方法
    }
}

字节流抽象类的子类:对象流

java.io.InputStream ---> java.io.ObjectInputStream
java.io.OutputStream ---> java.io.ObjectOutputStream
//对象流,对 对象 进行操作

对象流: Object0utputStream/ ObjectInputStream

  • 增强了缓冲区功能

  • 增强了读写8种基本数据类型和字符串功能

  • 增强了读写对象的功能:

    • read0bject() //从流中读取一个对象
    • write0bject (Object obj) //向流中写入一个对象
  • 使用流传输对象的过程称为序列化、反序列化:

    • 序列化:把内存中的对象写入到文件中(流中),write0bject (Object obj) ,

      ​ 同时要求我们的对象(序列化类)要实现Serializable接口(一个标记作用,说明这个类可以序 列化)

    • 反序列化:从文件(流)中读取对象,read0bject()

  1. ObjectInputStream:
    • 构造方法:ObjectInputStream (InputStream in)
  2. Object0utputStream:
    • 构造方法:ObjectOutputStream (OutputStream out)
    • void flush() //刷新该流的缓冲。

代码:

package com.wlw.io.demo02;
import java.io.Serializable;

//序列化类
public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {}

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {return name;}
    public void setName(String name) { this.name = name;}
    public int getAge() { return age;}
    public void setAge(int age) { this.age = age;}
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.wlw.io.demo02;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

/**
 * 使用ObjectOutputStream实现对象的序列化(写入)
 * 要求:我们的对象(序列化类)要实现Serializable接口(一个标记作用,说明这个类可以序列化)
 */
public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建对象流,需要传入一个节点流
        FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //2.序列化(写入文件)
        Student zhangsan = new Student("张三",20);
        oos.writeObject(zhangsan);

        //3.关闭流
        oos.close();//会调用flush() 方法
        System.out.println("序列化完毕");
    }
}
package com.wlw.io.demo02;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

/**
 * 使用ObjectInputStream反序列化(读取重构成对象)
 */
public class ObjectInputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建对象流,需要传入一个节点流
        FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);

        //2.读取(反序列化)
        Object object = ois.readObject(); //读完不能重复读,否则会抛异常java.io.EOFException
        Student student = (Student) object;

        //3.关闭流
        ois.close();//内部也会关闭 fis
        System.out.println("反序列化完毕");
        System.out.println(student.toString());
    }
}
序列化与反序列化的注意事项:
  1. 序列化类必须要实现Serializable接口。
  2. 序列化类中对象属性要求实现Serializable接口。
  3. 序列化版本号ID ,serialVersionUID, 保证序列化的类和反序列化的类是同一个类。
  4. 使用transient (瞬间的)修饰属性,这个属性不能序列化。
  5. 静态属性不能被序列化。
  6. 序列化多个对象,可以借助集合实现。麻烦点的可以一个一个序列化,再一个一个反序列化。

代码:

package com.wlw.io.demo02;
import com.sun.org.apache.xalan.internal.res.XSLTErrorResources_it;

import java.io.Serializable;

//序列化类
public class Student implements Serializable {
    /**
     * serivalVersionUID:序列化版本号ID
     */
    private static final long serivalVersionUID = 10L;
    private String name;
    //private Address address; //对象属性 也要实现Serializable接口。
    private transient int age;
    private static String country = "中国";

    public Student() {}

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {return name;}
    public void setName(String name) { this.name = name;}
    public int getAge() { return age;}
    public void setAge(int age) { this.age = age;}
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.wlw.io.demo02;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

/**
 * 使用ObjectOutputStream实现对象的序列化(写入)
 * 要求:我们的对象(序列化类)要实现Serializable接口(一个标记作用,说明这个类可以序列化)
 */
public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建对象流,需要传入一个节点流
        FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //2.序列化(写入文件)
        Student zhangsan = new Student("张三",20);
        Student lisi = new Student("李四",20);

        ArrayList<Student> arrayList = new ArrayList<>();
        arrayList.add(zhangsan);
        arrayList.add(lisi);

        oos.writeObject(arrayList);
        //oos.writeObject(zhangsan);
        //oos.writeObject(lisi);

        //3.关闭流
        oos.close();//会调用flush() 方法
        System.out.println("序列化完毕");
    }
}
package com.wlw.io.demo02;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

/**
 * 使用ObjectInputStream反序列化(读取重构成对象)
 */
public class ObjectInputStreamDemo {
    public static void main(String[] args) throws Exception{
        //1.创建对象流,需要传入一个节点流
        FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);

        //2.读取(反序列化)

        //Student student = (Student)ois.readObject(); //读完不能重复读,否则会抛异常java.io.EOFException
        //Student student2 = (Student)ois.readObject();

        ArrayList<Student> arrayList = (ArrayList<Student>) ois.readObject();

        //3.关闭流
        ois.close();//内部也会关闭 fis
        System.out.println("反序列化完毕");
        //System.out.println(student.toString());
        //System.out.println(student2.toString());
        System.out.println(arrayList.toString());
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悬浮海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值