JavaIO流(三)

6.转换流

不同编码读取出现乱码的问题:

  • 如果代码编码和被读取的文本文件编码是一致的,使用字符流读取文本时不会出现乱码
  • 如果代码编码和被读取的文本文件编码是不一致的,使用字符流读取文本时就会出现乱码

InputStreamReader(字符输入转换流)

是Reader抽象类下的实现类

  • 解决不同编码时,字符流读取文本内容乱码的问题
  • 解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了。
package com.IO.transform_stream;

import java.io.*;

public class InputStreamReaderTest02 {
    public static void main(String[] args) {

        try (
                //1.得到文件的原始字节流(GBK 的字节流形式)
                InputStream is = new FileInputStream("basic-grammar\\src\\yehuan09.txt");
                //2.把原始的字节输入流按照指定的字符集编码转换成字符输入流
                Reader isr = new InputStreamReader(is,"GBK");
                //3.把字符输入流包装成缓冲字符输入流
                BufferedReader br = new BufferedReader(isr);
                ){
            String line;
            while((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

OutputStreamWriter(字符输出转换流)(了解)

需要控制写出去的字符使用什么字符集编码,该咋整?

  • 调用String提供的getBytes方法解决
String data = "我爱你中国abc";
byte[] bytes = data.getBytes("GBK");
  • 使用字符输出转换流实现
    • 作用:可以控制写出去的字符使用什么字符集编码。
    • 解决思路:先获取文件字节输出流,再按照指定的字符集编码将其转成字符输出流,以后写出去的字符就会用该字符集编码了。
package com.IO.transform_stream;

import java.io.*;

public class OutputStreamWriterTest03 {
    public static void main(String[] args) {
        try (
                OutputStream os = new FileOutputStream("basic-grammar\\src\\yehuan09out.txt");
                Writer osw = new OutputStreamWriter(os,"GBK");
                BufferedWriter bw = new BufferedWriter(osw);
                ){
            bw.write("我是中国人abc");
            bw.newLine();
            bw.write("我是中国人123");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

7.打印流

PrintStream/PrintWriter(打印流)

PrintStream是字节输出流抽象类下的实现类

PrintWriter是字符输出流抽象类下的实现类

  • 作用:打印流可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去。
package com.IO.printstream;

import java.io.*;
import java.nio.charset.Charset;

public class PrintStreamTest01 {
    public static void main(String[] args) {

        try (
                //1.创建一个打印流管道
                //PrintStream ps =  new PrintStream("basic-grammar\\src\\yehuan10.txt",Charset.forName("GBK"));
                //PrintStream ps =  new PrintStream("basic-grammar\\src\\yehuan10.txt");
                //追加数据
                PrintWriter ps =  new PrintWriter(new FileOutputStream("basic-grammar\\src\\yehuan10.txt",true));
                ){
            ps.println(100);
            ps.println('a');
            ps.println("中国");
            ps.println(true);
            ps.println(9.5);

            ps.write(97);//'a'
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

PrintStream和PrintWriter的区别

  • 打印数据功能上是一模一样的:都是使用方便,性能高效(核心优势)
  • PrintStream继承自字节输出流OutputStream,因此支持写字节数据的方法
  • PrintWriter继承自字节输出流Writer,因此支持写符数据出去

打印流的一种应用:输出语句的重定向

System.out.println("志在千里");
  • 可以把输出语句的打印位置改到某个文件中去。
PrintStream ps = new PrintStream("文件地址");
System.setOut(ps);
package com.IO.printstream;

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class PrintTest01 {
    public static void main(String[] args) {
        System.out.println("老骥伏枥");
        System.out.println("志在千里");

        try (
                PrintStream ps = new PrintStream("basic-grammar\\src\\yehuan11.txt");
                ){
            // 把系统默认的打印流对象改成自己设置的打印流
            System.setOut(ps);
            System.out.println("烈士暮年");
            System.out.println("壮心不已");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

8.数据流

DataOutputStream(数据输出流)

  • 允许把数据和其类型一并写出去
package com.IO.data_stream;

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class DataOutputStreamTest1 {
    public static void main(String[] args) {
        try (
                //1.创建一个数据输出流包装低级的字节输出流
                DataOutputStream dos = new DataOutputStream(new FileOutputStream("basic-grammar\\src\\yehuan10out.txt"));
                ){
            dos.writeInt(97);
            dos.writeDouble(99.5);
            dos.writeBoolean(true);
            dos.writeUTF("夜欢");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

DataInputStream(数据输入流)

  • 用于读取数据输出流写出去的数据
package com.IO.data_stream;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

/*
    目标:使用数据输入流读取特定类型的数据。
 */
public class DataInputStreamTest2 {
    public static void main(String[] args) {
        try (
                DataInputStream dis = new DataInputStream(new FileInputStream("basic-grammar\\src\\yehuan10out.txt"));
                ){
            int i = dis.readInt();
            System.out.println(i);

            double d = dis.readDouble();
            System.out.println(d);

            boolean b = dis.readBoolean();
            System.out.println(b);

            String s = dis.readUTF();
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

9.序列化流

对象序列化:把Java对象写入到文件中去

对象反序列化:把文件里的Java对象读出来

ObjectOutputStream(对象字节输出流)

  • 可以把Java对象进行序列化:把Java对象写入到文件中去

User类:

package com.IO.object_stream;

import java.io.Serializable;

//注意:对象如果需要序列化,必须实现序列化接口
public class User implements Serializable {
    private String loginName;
    private String userName;
    private int age;
    private String passWord;

    public User() {
    }

    public User(String loginName, String userName, int age, String passWord) {
        this.loginName = loginName;
        this.userName = userName;
        this.age = age;
        this.passWord = passWord;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    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() {
        return "User{" +
                "loginName='" + loginName + '\'' +
                ", userName='" + userName + '\'' +
                ", age=" + age +
                ", passWord='" + passWord + '\'' +
                '}';
    }
}
package com.IO.object_stream;

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

public class Test01ObjectOutputStream {
    public static void main(String[] args) {


        try (
                //2.创建一个对象字节输出流包装原始的字节输出流。
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("basic-grammar\\src\\yehuan11out.txt"));
                ){
            //1.创建一个Java对象
            User u = new User("admin","夜欢",25,"123456");
            //3.序列化对象到文件中
            oos.writeObject(u);
            System.out.println("序列化对象成功!!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

注意:对象如果需要序列化,必须实现序列化接口(java.io.Serializable)

ObjectInputStream(对象字节输入流)

  • 可以把Java对象进行反序列化:把存储在文件中的Java对象读入到内存中来
package com.IO.object_stream;

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

public class Test02ObjectInputStream {
    public static void main(String[] args) {
        //1.创建一个对象字节输入流管道,包装 低级的字节输入流与源文件接通
        try (
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("basic-grammar\\src\\yehuan11out.txt"));
                ){
            User u = (User)ois.readObject();
            System.out.println(u);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//transient 这个成员变量将不参加序列化
private transient String passWord;

如果要一次序列化多个对象,咋整?

用一个ArrayList集合存储多个对象,然后直接对集合进行序列化即可。

注意:ArrayList集合已经实现了序列化接口!

10.补充知识:IO框架

什么是框架?

  • 解决,某类问题,编写的一套类、接口等,可以理解为一个半成品,大多框架都是第三方研发的
  • 好处:在框架的基础上开发,可以得到优秀的软件架构,并能提高开发效率
  • 框架的形式:一般是把类、接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去。

什么是IO框架

  • 封装了Java提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等。

导入commons-io-2.18.0.jar框架到项目中去

  • 在项目中创建一个文件夹:lib
  • 将commons-io-2.18.0.jar文件复制到lib文件夹
  • 在lib文件上点右键,选择ADD as Library -> 点击ok
  • 在类中导包使用

11.IO流最终完整体系

posted @ 2025-02-14 14:19  昼冷夜欢  阅读(9)  评论(0)    收藏  举报