IO流、输入、输出流

一、IO流

输入输出流: I input : O output

1.IO分类:

按照方向分: 输入流 和输出流

输入流: 读操作

输出流: 写操作

按照IO管道大小: 字节流: 一个字节一个字节的读写: 万能流

字符流: 一个字符一个字符读写: 读写文本文件

按功能分:

节点流:用于直接操作目标设备的流

处理流:是对一个已存在的流的连接和封装,通过对数据的处理为程序提供更强大、灵活的读写功能。

2.IO流类结构图:

4个抽象父类

字节输入流: InputStream

字节输出流: OutputStream

字符输入流: Reader

字符输出流: Writer

输入流主要方法:

read() 读方法

close() 关闭

输出流主要方法:

write() 写方法

close() 关闭

编写步骤:

  1. 创建IO流对象

  2. 读/写操作

  3. 关闭资源

二、输入、输出流

1.节点流

(1)字节节点流(万能流)

1.FileInputStream

FileInputStream fis  = null;
​
//1.构造方法
FileInputStream(File file) 
通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。  
FileInputStream(FileDescriptor fdObj) 
创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。  
FileInputStream(String name) 
通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。  
//第一个和第三个构造方法差不多,第一个适合方法调用,第三个平时少写一行代码
​
​
//2.应用
        try {
            //1.创建IO流对象
            fis = new FileInputStream("d:/hello.txt");
            //2.进行读写操作
            int rs = -1;
            while((rs=fis.read()) != -1){
                System.out.println((char)rs);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //3.关闭
            try {
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

字节一个个读取特别慢

 try {
//1.创建IO流对象
            fis = new FileInputStream("d:/hello.txt");
//2.进行读写操作
            int rs = -1;
//一个中文占三个字节
            byte[] b = new byte[5];
            while((rs=fis.read(b)) != -1){
                //read() 一下, 只读一个字节  编码  返回的读到内容编码
                //read(byte[] b) 把读到字节缓存到byte数组中 返回的是 读到的字节长度
                //System.out.print((char)rs);
                //把byte[] 转换为字符串
                System.out.println(rs);
                //String(byte[], offset, len)
                // 从byte[] 数组中指定offset下标开始, 读len个字节
                String s = new String(b,0,rs);
                System.out.println(s);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //3.关闭
            try {
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

2.FileOutputStream

FileOutputStream fos  = null;
//1.构造方法
FileOutputStream(File file) 
创建文件输出流以写入由指定的 File对象表示的文件。  
FileOutputStream(File file, boolean append) 
创建文件输出流以写入由指定的 File对象表示的文件。  
FileOutputStream(FileDescriptor fdObj) 
创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。  
FileOutputStream(String name) 
创建文件输出流以指定的名称写入文件。  
FileOutputStream(String name, boolean append) 
创建文件输出流以指定的名称写入文件。  
//2. FileOutputStream往文件写入内容
FileOutputStream  fos = null;
        try {
            //1.创建IO对象
            fos = new FileOutputStream("d:/a.txt",true);
            //2.写
            String  str = "\nhello world\n";
            //需要把字符串转换为byte数组
            byte[] bytes = str.getBytes();
            fos.write(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //3.关闭
            if(fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
​

(2)字符节点流(.txt、.java能用记事本打开的文件)

1.FileReader文件符输入流

FileReader fr = null;
        try {
            //1.创建IO流对象
            fr = new FileReader("d:/hello.txt");
            //2.进行读写操作
            //int rs = fr.read();
            int rs = -1;
            while((rs = fr.read()) != -1){
                System.out.println((char)rs);
            }
        } catch (
                FileNotFoundException e) {
            e.printStackTrace();
        } catch (
                IOException e) {
            e.printStackTrace();
        }finally{
            //3.关闭
            try {
                if(fr != null){
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

2.FileWriter文件符输出流

FileWriter fw = null;
        try {
            //1.创建IO对象
            fw = new FileWriter("d:/a.txt",true);
            //2.写
            String  str = "\n你好 世界\n";
            fw.write(str);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //3.关闭
            if(fw!=null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
}
 

2.内存流

唯一一种从网络获取二进制数据的(意义不大、一般不存在内存里)

当输出流的目的和输入流的源是内存时,这样两端都是内存

1. ByteArrayInputStream把内存某个字节数组中数据读取出来
  1. ByteArrayOutputStream把数据写到内存的字节数组中

 ByteArrayOutputStream boas = null;
        try {
            boas = new ByteArrayOutputStream();
            String str = "hello world";
            //写操作
            boas.write(str.getBytes());
            //刷新
            boas.flush();
​
            //得到字节数组
            byte[] b = boas.toByteArray();
​
            String s = new String(b);
            System.out.println(s);
​
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(boas!=null){
                try {
                    boas.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

3.缓冲流:(处理流)

不能直接接只能接到别的输入输出流

自带缓冲区、byte字节流、char[]字符流

1.BufferedReader

FileReader fr = null;
        BufferedReader br = null;
        try {
            //创建一个节点流
            fr = new FileReader("d:/hello.txt");
            //创建处理流
            br = new BufferedReader(fr);
            //读取  读到文件末尾: 返回: null
           // String line = br.readLine();
            String line = null;
            //readLine() 遇到一个换行符结束读
            while((line=br.readLine()) != null){
                System.out.println(line);
            }
​
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

2.BufferedWriter

缓存输出流有一个8kb的缓存区

1.满了就自动输出写到文件里

2.手动调用flush(),不管满没满立即写到文件里

3.close方法,关闭前刷新

    //FileWriter fw = null;
        FileOutputStream fos = null;
        BufferedWriter bw = null;
        OutputStreamWriter osw = null;
​
        //fw = new FileWriter("d:/hello.txt",true);
        fos = new FileOutputStream("d:/hello.txt",true);
        osw = new OutputStreamWriter(fos);
        bw = new BufferedWriter(osw);
​
        bw.write("呵呵");
        //换行
        bw.newLine();
        bw.write("嘿嘿");
​
        //刷新缓冲区
        //bw.flush();
​
​
        //倒序关
        bw.close();
        osw.close();
        fos.close();

4.转换流

把字节流转换为字符流

1.InputSteamReader()

2.OutputSteamWrite()

5.打印流

PrintSteam 只有输出流、打印输出流:额外提供了一个打印方法print、println

1.字节打印流

2.字符打印流 PrintWriter

两个构造方法

常用构造方法
PrintWriter(System.out);
PrintWriter(System.out,true/false);
是否自动清除缓冲区
        PrintWriter pw = null;
        //打印到控制台
       // pw = new PrintWriter(System.out);
​
        pw = new PrintWriter("d:/test.txt");
        //打印方法
        pw.println("你好:");
        pw.println("中国");
        pw.println(true);
        pw.println(new Object());
        pw.close();

6.对象流

可以读写对象

ObjectInputStream: 对对象进行反序列化, 读取这个字节序列,反序列化成为一个java对象

常用构造方法
​
ObjectInputStream(InputStream in) 
创建从指定的InputStream读取的ObjectInputStream。 

ObjectOutputStream:对对象进行序列化, 把这个对象转换为字节序列, 写出去

ObjectInputStream,ObjectOutputStream 是处理流, 需要一个字节流

常用构造方法
​
ObjectOutputStream(OutputStream out) 
创建一个写入指定的OutputStream的ObjectOutputStream。 

常见错误:

1.JDK默认禁止序列化 对某个对象进行序列化, 需要对这个对象开启允许序列化

只要让这个类实现java.io.Serizalizable接口

public class Student implements Serializable {

2.已经读到文件末尾, 还在读,产生该异常

readObject() 没有一个特殊值,表示读到文件末尾

一个类一旦设置serialVersionUID, 后期不能随意改动

如果某个属性敏感的,不想参与序列化, 使用transient关键字修饰

//提供一个常量: serialVersionUID  序列化id  默认值1
    //private static final long serialVersionUID = 1L;
    //5191370656703224314L 序列化对象,使用序列化id:
​
    // 修改5191370656703226666L 不一样
    private static final long serialVersionUID = 5191370656703224314L;
​
    private int id;
    private String name;
    private String sex;
    private int age;
    // transient: 修饰的属性,不会进行序列化,写入到文件中
    private transient String password;
​
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getSex() {
        return sex;
    }
​
    public void setSex(String sex) {
        this.sex = sex;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    /*
    * 方便测试, 方便打印这个对象,输出的是对象属性值
    */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Student").append('[')
                .append("id=")
                .append(id)
                .append(",name=")
                .append(name)
                .append(",sex=")
                .append(sex)
                .append(",age=")
                .append(age)
                .append(",password=")
                .append(password)
                .append(']');
        return sb.toString();
    }
​
    public Student(int id, String name, String sex, int age, String password) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.password = password;
    }
​
    public Student() {
    }

序列化

A程序: 把这个对象使用输出流, 把这个对象写出去: 把这个对象打散成字节序列: 序列化:

为了能让对象进行保存,或者进行网络传输

B程序: 使用输入流, 读取这个对象: 把字节序列重新组装成一个java对象: 反序列化

示例:将Student对象保存至文件中(序列化)

//1.创建一个学生类对象
        Student stu = new Student(1,"张三","男",21,"123456");
        Student stu1 = new Student(2,"李四","男",21,"156");
        Student stu2 = new Student(3,"王五","男",21,"1236");
        //2.保存到文件中,   输出流, 使用ObjectOutputStream
        ObjectOutputStream oos = null;
        FileOutputStream fos = null;
        // 从盘符开始, "d:/stu.txt"  绝对路径
        // "stu.txt": 相对路径
        try {
            fos = new  FileOutputStream("stu.txt");
            oos = new ObjectOutputStream(fos);
            //2.保存到文件中,  writeObject(Object )
            //写int类型的数据, 表示写了多少个对象
            oos.writeInt(3);
            oos.writeObject(stu);
            oos.writeObject(stu1);
            oos.writeObject(stu2);
            oos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //倒序关
            try{
                if(oos != null){
                    oos.close();
                }
                if(fos != null){
                    fos.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        //3.读取这个文件, 获取这个对象
​
反序列化(读出来)

FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream("stu.txt");
            ois = new ObjectInputStream(fis);
​
            //读取对象  反序列化
            //循环读取
            //readObject()
            Student stu = null;
           /* while((stu =(Student)ois.readObject()) != null){
                System.out.println(stu);
            }*/
            //读第一个数据 int
            int count = ois.readInt();
            for (int i = 0; i <count ; i++) {
                stu =(Student)ois.readObject();
                System.out.println(stu);
            }
​
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            //倒序关
            try{
                if(ois != null){
                    ois.close();
                }
                if(fis != null){
                    fis.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值