io流总结、序列化和反序列化、Properties集合

本文详细介绍了Java中的IO流,包括字节流和字符流的分类、节点流与处理流的区别,以及字节输出流和输入流的使用方法。提供了代码示例展示如何使用字节流和字符流进行文件复制。此外,还涵盖了缓冲流的使用以及字符缓冲流的特殊读写方法。最后,提及了Java序列化和反序列化的基本概念以及Properties集合的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO流

1、IO流的分类

按流向分类:
输入流(读取数据)
输出流(写出数据)
按数据类型分类:
字节流
字节输入流 读取数据 InputStream
字节输出流 写出数据 OutputStream
字符流
字符输入流 读取数据 Reader
字符输出流 写出数据 Writer

2、节点流和处理流的区别

InputStream & OutputStreamReader & Writer 乃节点流,前面加File之类的名词的节点流其余加动词的均为处理流,想着处理流是加在节点流的基础上的。
java的输入流主要是InputStream和Reader作为基类,而输出流则是主要由outputStream和Writer作为基类。它们都是一些抽象基类,无法直接创建实例。
字节流主要是由InputStream和outPutStream作为基类,而字符流则主要有Reader和Writer作为基类。

3、字节输出流OutputStream

是一个抽象类,不能被直接实例化,需要找一个具体实现子类来实例化 FileOutputStream:

构造方法:
FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。

字节输出流的操作步骤:
1、创建字节输出流对象
2、调用方法,写数据
3、释放资源

字节输出流写数据的几种方法:
public void write(int b)
public void write(byte[] b)
public void write(byte[] b,int off,int len)

4、字节输入流InputStream

同理用FileInputStream进行实例化

FileInputStream的构造方法
FileInputStream(File file)
FileInputStream(String name)

字节输入流读取数据两种方式:
            FileInputStream的成员方法
                public int read()一次只能读取一个字节,返回的是ASCII码值强制类型转换
                public int read(byte[] b)一次读取一个字节数组
            //第一种遍历方式
              int i=0;
              while ((i=fis.read())!=-1){
              System.out.print((char) i);
              }

            //第二种遍历方式
            byte[] bytes = new byte[1024];
            int length=0;
            while ((length=fis.read(bytes))!=-1){
                System.out.println(new String(bytes,0,length));
            }

5、代码示例1(文本复制)

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

/*
        把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

        输入流
            InputStream -- FileInputStream
            一次读取一个字节
            一次性读取一个字节数组
            a.txt

        输出流
            OutputStream -- FileOutputStream
            一次写一个int类型数值
            一次写一个字节数组
            一次写一个字节数组的一部分
            b.txt


 */
public class CopyFileDemo1 {
    public static void main(String[] args) throws Exception {
        //1、创建字节输入流对象和字节输出流对象
        FileInputStream fis = new FileInputStream("a.txt");
        FileOutputStream fos = new FileOutputStream("f.txt");

        //2、读取数据
        //a: 一次读取一个字节
//        int i = 0;
//        while ((i=fis.read())!=-1){
            System.out.println();
//            fos.write(i);
//        }

        //b: 一次读取一个字节数组
        byte[] bytes = new byte[1024];
        int length = 0;
        while ((length = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, length);
        }

        //释放资源
        fos.close();
        fis.close();
    }
}

6、代码示例2(照片复制)

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

/*
        把当前项目下的冯提莫.jpg复制到当期项目下day23目录下

        数据源:从哪来
        冯提莫.jpg -- 读取数据 -- InputStream -- FileInputStream

        目的地:到哪里去
        com\\shujia\\wyh\\day23\\ftm.jpg -- 写出数据 -- OutputStream -- FileOutputStream
 */
public class CopyJpgDemo1 {
    public static void main(String[] args) throws Exception {
        //创建字节输入流对象和字节输出流对象
        FileInputStream fis = new FileInputStream("冯提莫.jpg");
        FileOutputStream fos = new FileOutputStream("src\\com\\shujia\\wyh\\day23\\ftm.jpg");

        byte[] bytes = new byte[1024];
        int length = 0;
        while ((length = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, length);
        }

        //释放资源
        fos.close();
        fis.close();
    }
}

7、字节缓冲流

缓冲区类(高效类)
字节缓冲输出流
BufferedOutputStream
字节缓冲输入流
BufferedInputStream

8、字符流

字符输入流
Reader
字符输出流
Writer

OutputStreamWriter: 字符输出流 是以字节流加上编码表得到的一个转换流,后期写数据的时候可以根据自己指定的编码进行写入
public OutputStreamWriter(OutputStream out)
创建一个使用默认字符编码的OutputStreamWriter。根据默认的编码用字符作为桥梁将字节流的数据转换为字符流
public OutputStreamWriter(OutputStream out,String charsetName)
InputStreamReader: 字符输入流
public InputStreamReader(InputStream in)
读取数据,根据默认的编码用字符作为桥梁将字节流的数据转换为字符流
public InputStreamReader(InputStream in,String charsetName)
读取数据,根据指定的编码用字符作为桥梁将字节流的数据转换为字符流
根据指定的编码用字符作为桥梁将字节流的数据转换为字符流
把字节流转化字符流
字符流 = 字节流 + 编码表

OutputStreamWriter写数据的方法:
            public void write(int c)
            public void write(char[] cbuf)
            public void write(char[] cbuf,int off,int len)
            public void write(String str)
            public void write(String str,int off,int len)

flush()和close()的区别:
1、调用完flush()后,流对象并没有关闭,还能继续写数据。
2、调用完close()后,流对象关闭了,后续无法再通过这个对象写数据。

InputStreamReader:字符输入流
            读取数据的方法:
                public int read()
                public int read(char[] cbuf)

代码示例(用字符流进行复制文件)

import java.io.*;

/*
把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

        数据源:
            a.txt -- 读取数据 -- 字符输入流 -- Reader -- InputStreamReader

        目的地:
            b.txt -- 写出数据 -- 字符输出流 -- Writer -- OutputStreamWriter
 */
public class CopyFileDemo2 {
    public static void main(String[] args) throws IOException {
        //创建字符输入流对象和字符输出流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("d.txt"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("dd.txt"));
        //第一种
//        int i=0;
//        while ((i=isr.read())!=-1){
//            osw.write(i);
//        }

        //第二种
        char[] chars = new char[1024];
        int length=0;
        while ((length=isr.read(chars))!=-1){
            osw.write(chars,0,length);
        }
        //释放空间
        osw.close();
        isr.close();

    }
}

用字符缓冲流复制文本文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

/*
            把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

            数据源:
                a.txt -- 读取数据 -- 字符输入流 -- Reader -- InputStreamReader -- FileReader -- BufferedReader

            目的地:
                b2.txt -- 写入数据 -- 字符输出流 -- Writer -- OutputStreamWriter -- FileWriter -- BufferedWriter
 */
public class CopyFileDemo4 {
    public static void main(String[] args) throws Exception {
        //1、创建字符缓冲输入流对象和字符缓冲输出流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("b2.txt"));

        //一次读写一个字符数组
        char[] chars = new char[1024];
        int length = 0;
        while ((length= br.read(chars))!=-1){
            bw.write(chars,0,length);
            bw.flush();
        }

        //释放资源
        bw.close();
        br.close();

    }
}

字符缓冲流的特殊读写方法:

       字符缓冲流的特殊读写方法:
       BufferedWriter:
            void newLine()
            写一行行分隔符。 行分隔符字符串由系统属性line.separator定义,并不一定是单个换行符('\ n')字符。

       BufferedReader:
            public String readLine()
            读一行文字。 一行被视为由换行符('\ n'),回车符('\ r')中的任何一个或随后的换行符终止。

代码示例

把ArrayList集合中的字符串数据存储到文本文件

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/*
把ArrayList集合中的字符串数据存储到文本文件
 */
public class IOTest1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("java");
        list.add("hello");
        list.add("world");
        list.add("java");

        BufferedWriter bw=null;
        try {
            bw = new BufferedWriter(new FileWriter("a.txt"));
            for(String s:list){
                bw.write(s);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

数据排序

import java.io.*;
import java.util.Arrays;

/*
已知s.txt文件中有这样的一个字符串:“hcexfgijkamdnoqrzstuvwybpl”
            请编写程序读取数据内容,把数据排序后写入ss.txt中。
 */
public class IOTest2 {
    public static void main(String[] args)throws IOException {
        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("s.txt"));
        String s = br.readLine();
        br.close();

        //将字符串转化为字符数组
        char[] chars = s.toCharArray();

        //调用Arrays工具类sort方法
        Arrays.sort(chars);

        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("s.txt"));
        bw.write(chars);
        bw.flush();
        bw.close();
    }
}

操作基本数据的流

注意:读取的数据要和写入的数据一样

import java.io.*;

//读的顺序与写顺序一致
public class DataInputStreamDemo1 {
    public static void main(String[] args) throws IOException {
//        write();
        read();
    }

    private static void read() throws FileNotFoundException, IOException {
        DataInputStream dis = new DataInputStream(new FileInputStream("b3.txt"));
//        byte b = dis.readByte();
//        System.out.println(b);
//        short s = dis.readShort();
//        System.out.println(s);
//        int i = dis.readInt();
//        System.out.println(i);

        int i = dis.readInt();
        System.out.println(i);
        short s = dis.readShort();
        System.out.println(s);
        byte b = dis.readByte();
        System.out.println(b);

        long l = dis.readLong();
        System.out.println(l);
        float f = dis.readFloat();
        System.out.println(f);
        double d = dis.readDouble();
        System.out.println(d);
        char ch = dis.readChar();
        System.out.println(ch);
        boolean bb = dis.readBoolean();
        System.out.println(bb);
        dis.close();
    }

    private static void write() throws IOException {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                "dos.txt"));
        dos.writeByte(1);
        dos.writeShort(20);
        dos.writeInt(300);
        dos.writeLong(4000);
        dos.writeFloat(12.34f);
        dos.writeDouble(12.56);
        dos.writeChar('a');
        dos.writeBoolean(true);
        dos.close();
    }
}

序列化和反序列化

序列化:
把对象按照流一样的方式存到文本文件或者数据库或者在网络中传输
对象 – 流数据: ObjectOutputStream
反序列化:
把文本文件中的流对象数据或者网络中的流数据还原成一个对象
流数据 – 对象: ObjectInputStream

serialVersionUID 有两种显示的生成方式

一是默认的 1L ,比如: private static final long serialVersionUID = 1L;

二是根据类名、接口名、成员方法及属性等来生成一个 64 位的哈希字段
当实现 java.io.Serializable 接口的类没有显式地定义一个 serialVersionUID 变量时候,Java 序 列化机制会根据编译的 Class 自动生成一个 serialVersionUID 作 序 列 化 版 本 比 较 用 ,这 种 情 况 下,如果 Class 文件 ( 类名,方法明等 ) 没有发生变化 ( 增加空格,换行,增加注释等等 ) ,就算 再编译多次, serialVersionUID 也不会变化的

光标放在类名上:alt+enter
就会自动生成private static final long serialVersionUID = -1761396628325683011L;

Transient 关键字
Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变 量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

Java 序列化的一些简单总结
1、Java序列化只是针对对象的状态进行保存,至于对象中的方法,序列化不关心
2、当一个父类实现了序列化,那么子类会自动实现序列化,不需要显示实现序列化接口
3、当一个对象的实例变量引用了其他对象,序列化这个对象的时候会自动把引用的对象也进 行序列化(实现深度克隆)
4、当某个字段被申明为transient后,默认的序列化机制会忽略这个字段
被申明为 transient 的字段,如果需要序列化,可以添加两个私有方法:writeObject 和 readObject

Properties集合

Properties 可保存在流中或从流中加载,属性列表中每个键及其对应值都是一个字符串,继承于 Hashtable

Properties类的特点
a)该集合不能写泛型
b)可以持久化的属性集。键值可以存储到集合中,也可以存储到硬盘、U盘等
c)可以和IO流有关的技术结合使用
Properties集合是一个双列集合,key和value默认都是字符串

import java.util.Properties;

/*
        user: root
        password: 123456
 */
public class PropertiesDemo {
    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "123456");


        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        System.out.println(user + "--" + password);


    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值