文章目录

  • IO流常用类
  • InputStream:字节输入流
  • InputStream 常用的子类
  • 1.FileInputStream:文件输入流
  • 案例
  • read()方法
  • 2.FileOutputStream:字节输出流
  • 案例
  • FileReader 和 FileWriter介绍
  • FileReader相关方法
  • 案例
  • 相关API
  • FileWriter常用方法
  • 案例
  • 相关API
  • 注意
  • 节点流和处理流
  • 基本介绍
  • 节点流
  • 包装流
  • 节点流和处理流的区别和联系
  • 处理流(包装流)的功能主要体现在以下两个方面
  • 图表汇总
  • 处理流(包装流)底层机制剖析==修饰器设计模式
  • 举例
  • 结论
  • 处理流(专题)
  • BufferedReader和BufferedWriter
  • BufferedReader案例
  • BufferedWriter案例
  • 知识点
  • 综合应用
  • 注意
  • BufferedInputStream 和 BufferedOutputStream
  • ObjectInputStream和ObjectOutputStream
  • 序列化和反序列化
  • 序列化案例
  • 反序列化案例
  • 细节
  • 标准输入输出流
  • 介绍
  • 结论
  • 转换流
  • 引出转换流
  • InputStreamReader
  • 案例
  • OutputStreamWriter
  • 案例
  • 打印流
  • PrintStream
  • 案例代码
  • PrintWriter
  • 案例代码
  • Properties类
  • 基本介绍
  • 1.专门用于读写配置文件的集合类
  • 2.注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String
  • 常见方法
  • unicode码查询工具
  • 需求
  • 传统方法
  • 使用Properties类可以方便实现
  • 案例Properties类创建修改文件


IO流常用类

InputStream:字节输入流

InputStream抽象类是所有类字节输入流的超类

InputStream 常用的子类

java层 设备节点 java节点类_java

1.FileInputStream:文件输入流

案例
  1. 请使用FileInputStream 读取 hello.txt 文件,并将文件内容显示到控制台。
read()方法
package com.taotao.inputstream;

import org.testng.annotations.Test;

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

/**
 * Create By 刘鸿涛
 * 2022/1/26 9:32
 * 演示FileInputStream的使用
 */
public class FileInputStream_ {
    public static void main(String[] args) {

    }
    /*
        演示读取文件
     */
    @Test
    public void readFile01(){
        String filePath = "d:\\hello.txt";
        int readDate = 0;
        //把fileInputStream定义到这里,扩大作用域
        FileInputStream fileInputStream = null;
        try {
            //创建 FileInputStream 对象,用于读取 文件
            fileInputStream = new FileInputStream(filePath);

            //从该输入流读取一个字节的数据,如果没有输入可用,此方法将阻止。
            //如果返回-1,表示读取完毕
            while((readDate = fileInputStream.read())!= -1){
                System.out.print((char)readDate);   //转成char显示
            }

            //IO异常
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //如果不关闭流,会浪费资源
            //关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

read(byte[] b) 方法

package com.taotao.inputstream;

import org.testng.annotations.Test;

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

/**
 * Create By 刘鸿涛
 * 2022/1/26 9:32
 * 演示FileInputStream的使用
 */
public class FileInputStream_ {
    public static void main(String[] args) {

    }
    /*
        演示读取文件
     */
    @Test
    public void readFile01(){
        String filePath = "d:\\hello.txt";
        //字节数组
        byte[] buf = new byte[8]; //一次读取8个字节
        int readLen = 0;
        //把fileInputStream定义到这里,扩大作用域
        FileInputStream fileInputStream = null;
        try {
            //创建 FileInputStream 对象,用于读取 文件
            fileInputStream = new FileInputStream(filePath);

            //从该输入流读取最多b.length字节的数据到字节数组。此方法将阻塞,直到某些输入可用
            //如果返回-1,表示读取完毕
            //如果读取正常,返回实际读取的字节数
            while((readLen = fileInputStream.read(buf))!= -1){
                System.out.println(new String(buf, 0, readLen));   //
            }

            //IO异常
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //如果不关闭流,会浪费资源
            //关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

java层 设备节点 java节点类_开发语言_02

2.FileOutputStream:字节输出流

package com.taotao.outputstream_;

import org.testng.annotations.Test;

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

/**
 * Create By 刘鸿涛
 * 2022/1/26 12:19
 */
public class FileOutStream01 {
    public static void main(String[] args) {

    }
    /**
     *演示使用FileOutputStream 将数据写到文件中
     * 如果该文件不存在,则创建该文件
     */
    @Test
    public void writeFile(){
        //创建 FileOutputStream对象
        /**
         * 注意!
         * 1.new FileOutputStream(filePath)创建方式,当写入内容时,会覆盖原来的内容
         * 2.new FileOutputStream(filePath,true)创建方式,当写入内容是,是追加到文件后面,
         */
        String filePath = "d:\\a.txt";
        //扩大作用域
        FileOutputStream fileOutputStream = null;

        try {
            //得到 FileOutputStream对象 对象                     ,这里的true是append,根据是否需要覆盖填写
            fileOutputStream = new FileOutputStream(filePath,true);

            //1.写入一个字节
//            fileOutputStream.write('a');

            //2.写入字符串
            String str = "hello,world";
            //str.getBytes() 可以把 字符串 -> 字节数组
//            fileOutputStream.write(str.getBytes());

            //3.write(byte[] b,int off, int len)将 len字节从位于偏移量 off的指定字节数组写入此文件输出流
            fileOutputStream.write(str.getBytes(), 0, str.length());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
}
案例
  1. 要求:编程完成图片/音乐 的拷贝

java层 设备节点 java节点类_输入流_03

package com.taotao.outputstream_;

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

/**
 * Create By 刘鸿涛
 * 2022/1/26 14:31
 */
public class FileCopy {
    public static void main(String[] args) {
        //完成 文件拷贝,将d:\\jing.jpg 拷贝 c:\\
        //思路分析
        //1.创建文件的输入流 ,将文件读入到程序
        //2.创建文件的输出流,将读取到的文件数据,写入到指定的文件
        String filePath = "d:\\\\jing.jpg";
        String copyFilePath = "d:\\demo\\jing.jpg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;

        try {
            //文件输入流
            fileInputStream = new FileInputStream(filePath);

            //文件输出流
            fileOutputStream = new FileOutputStream(copyFilePath);

            //定义一个字节数组,提高读取效果
            byte[] buf = new byte[1024];   //一次读取1024个字节
            int readLen = 0;
            while((readLen = fileInputStream.read(buf)) != -1){
                //读取到后,就写入到文件 通过 fileOutputStream
                //即,是一边读,一边写
                fileOutputStream.write(buf, 0, readLen);    //一定要用这个方法
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭输入流和输出流,及时释放资源
                if(fileInputStream != null){
                    fileInputStream.close();
                }
                if(fileOutputStream != null){
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

FileReader 和 FileWriter介绍

java层 设备节点 java节点类_后端_04

java层 设备节点 java节点类_java层 设备节点_05

FileReader 和 FileWriter 是字符流,即按照字符来操作io

FileReader相关方法

  1. new FileReader(File/String)
  2. read:每次读取单个字符,返回该字符,如果是到文件末尾返回-1
  3. read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1

案例

package com.taotao.reader;


import org.testng.annotations.Test;

import java.io.FileReader;
import java.io.IOException;

/**
 * Create By 刘鸿涛
 * 2022/1/27 7:45
 */
public class FileReader_ {
    public static void main(String[] args) {

    }
    /**
     * 单个字符读取文件
     */
    @Test
    public void readFile01() {
        String filePath = "d:\\story.txt";
        FileReader fileReader = null;
        //后面需要转化char
        int data = 0;
        //1.创建FileReader对象
        try {
            fileReader = new FileReader(filePath);
            //循环读取 使用read
            while ((data = fileReader.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *多个字符读取
     */
    @Test
    public void readFile02() {
        String filePath = "d:\\story.txt";
        FileReader fileReader = null;
        int readLen = 0;
        //一次读取8个字符
        char[] buf = new char[8];
        //1.创建FileReader对象
        try {
            fileReader = new FileReader(filePath);
            //循环读取 使用read(buf),返回的是实际读取到的字符数
            //如果返回-1,说明到文件结束
            while ((readLen = fileReader.read(buf)) != -1) {
                System.out.print(new String(buf, 0, readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

相关API

  1. new String(char[]):将char[]转换成String
  2. new String(char[],off,len):将char的指定部分转换成String

FileWriter常用方法

  1. new FileWriter(File/String):覆盖模式,相当于流的指针在首端
  2. new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
  3. write(int):写入单个字符
  4. write(char[]):写入指定数组
  5. write(char[],off,len):写入指定数组的指定部分
  6. write(String):写入整个字符串
  7. write(String,off,len):写入字符串的指定部分

案例

使用FileWriter将“风雨之后,定见彩虹”写入到note.txt文件中,注意细节

package com.taotao.writer_;

import java.io.FileWriter;
import java.io.IOException;

/**
 * Create By 刘鸿涛
 * 2022/1/27 8:40
 */
public class FileWriter_ {
    public static void main(String[] args) {
        FileWriter fileWriter = null;
        String filePath = "d:\\story.txt";
        char[] arr = {'1','2'};
        try {
            fileWriter = new FileWriter(filePath, false);    //true表示追加

//            1. write(int):写入单个字符
            fileWriter.write("H");      //一定要关闭流,不然语句无效!!!

//            2. write(char[]):写入指定数组
            fileWriter.write(arr);                              //12

//            3. write(char[],off,len):写入指定数组的指定部分
            fileWriter.write("arr".toString(),0, 1);  //1

//            4. write(String):写入整个字符串
            fileWriter.write("刘鸿涛大大");      //刘鸿涛大大

//            5. write(String,off,len):写入字符串的指定部分
            fileWriter.write("刘鸿涛大大",0,4);
            //在数据量大的情况下,可以使用循环操作

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileWriter != null){
//                    fileWriter.flush();

                    //关闭文件流,等价 flush() + 关闭
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

相关API

String类

toCharArray:将String转换为char[]

注意

FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定的文件!

节点流和处理流

基本介绍

分类

字节输入流

字节输出流

字符输入流

字符输出流

抽象基类

InputStream

OutputStream

Reader

Writer

访问文件

FileInputStream

FileOutputStream

FileReader

FileWriter

访问数组

ByteArrayInputStream

ByteArrayOutputStream

CharArrayReader

CharArrayWriter

访问管道

PipedInputStream

PipedOutputStream

PipedReader

PipedWriter

访问字符串

StringReader

StringWriter

缓冲流

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

转换流

InputStreamReader

OutputStreamWriter

对象流

ObjectInputStream

ObjectOutputStream

抽象基类

FilterInputStream

FilterOutputStream

FilterReader

FilterWriter

打印流

PrintStream

PrintWriter

推回输入流

PushBackInputStream

PushbackReader

特殊流

DataInputStream

DataOutputStream

节点流

  1. 节点流可以从一个特点的数据源读写数据,如FileReader、FileWriter
  2. 简单来说:节点流就是你在市场买了只鸡,外卖员送的就是鸡

java层 设备节点 java节点类_开发语言_06

包装流

  1. 处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter
  2. 简单来说:包装流就是你买了只鸡,外卖员给你送的是红烧鸡

java层 设备节点 java节点类_后端_07

节点流和处理流的区别和联系

  1. 节点流是底层流/低级流,直接跟数据源相接
  2. 处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的写法来完成输入输出
  3. 处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
处理流(包装流)的功能主要体现在以下两个方面
  1. 性能的提高:主要以增加缓冲的方式来提高输入输出的效率
  2. 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

图表汇总

java层 设备节点 java节点类_java层 设备节点_08

处理流(包装流)底层机制剖析==修饰器设计模式

举例

我们先创建两个节点流,分别继承抽象类Reader_

StringReader_类

package com.taotao.writer_;

/**
 * Create By 刘鸿涛
 * 2022/1/27 11:43
 * 节点流
 */
public class StringReader_  extends Reader_{
    public void readString(){
        System.out.println("读取字符串");
    }
}

FileReader_类

package com.taotao.writer_;

/**
 * Create By 刘鸿涛
 * 2022/1/27 11:41
 * 节点流
 */
public class FileReader_ extends Reader_ {
    public void readFile(){
        System.out.println("对文件进行读取");
    }
}

抽象类Reader_

package com.taotao.writer_;

/**
 * Create By 刘鸿涛
 * 2022/1/27 11:40
 */
public abstract class Reader_ { //抽象类
    public void readFile(){}
    public void readString(){}
}

示范包装流BuffereReader_继承抽象类Reader_,利用多态

package com.taotao.writer_;



/**
 * Create By 刘鸿涛
 * 2022/1/27 11:52
 * 做成处理流(包装流)
 */
public class BufferedReader_ extends Reader_ {
    private Reader_ reader_; //属性是 Reader_类型
	
    //接手Reader_子类对象
    public BufferedReader_(Reader_ reader_){
        this.reader_ = reader_;
    }
    
    //这边封装一层,还是调用自己的方法,也是可以的
    public void readFile(reader_){
        this.reader_ = reader_;
    }

    //===================================================
   	//这边我们可以扩展功能
    //让方法更加灵活,多次读取文件,或者加缓冲char[]...
    public void readFiles(int num){
        for(int i = 0; i < num; i++){
            reader_.readFile();
        }
    }

    //扩展 readString,批量处理字符串数据
    public void readStrings(int num){
        for(int i = 0; i < num; i++){
            reader_.readString();
        }
    }
}

我们创建Text类,测试

package com.taotao.writer_;

/**
 * Create By 刘鸿涛
 * 2022/1/27 11:56
 */
public class Test {
    public static void main(String[] args) {
        BufferedReader_ bufferedReader_ = new BufferedReader_(new FileReader_());
        BufferedReader_ bufferedReader_1 = new BufferedReader_(new StringReader_());
//        bufferedReader_.readFiles(10);
        bufferedReader_1.readStrings(1);
    }
}
结论
  • 统一到一个抽象方法里,调用时用动态绑定机制绑定到它的实现子类

处理流(专题)

BufferedReader和BufferedWriter

java层 设备节点 java节点类_java_09

  • BufferedReader 和 BufferedWriter 属于字符流,是按照字符来读取数据的
  • 关闭时,只需要关闭外层流即可
  • 主要用来处理非【二进制】文件

BufferedReader案例

  • 使用BufferedReader读取文本文件,并显示在控制台
package com.taotao.reader_;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Create By 刘鸿涛
 * 2022/1/28 7:49
 * 演示bufferedreader 使用
 */
public class BufferedReader_ {
    public static void main(String[] args) throws Exception {
        String filePath = "d:\\story.txt";
        //创建bufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String line;

        //1.bufferedReader.readLine()) 是按行读取
        //2.如果不等于空,他就执行
        while((line = bufferedReader.readLine()) != null){
            System.out.println(line);
        }

        //关闭流,这里注意,只需要关闭 BufferedReader,因为底层会自动关闭节点流FileReader
        bufferedReader.close();
        //底层

//        public void close() throws IOException {
//            synchronized (lock) {
//                if (in == null)
//                    return;
//                try {
//                    in.close();       //in就是传入的FileReader
//                } finally {
//                    in = null;
//                    cb = null;
//                }
//            }
//        }
    }
}

BufferedWriter案例

使用BufferedWriter 将“文本”写入到文件中

package com.taotao.writer_;

import java.io.BufferedWriter;
import java.io.FileWriter;

/**
 * Create By 刘鸿涛
 * 2022/1/28 8:19
 */
public class BufferedWriter_ {
    public static void main(String[] args)throws Exception {
        String writerPath = "d:\\hello.txt";
        //写入时一定要注意是否覆盖
        BufferedWriter bw = new BufferedWriter(new FileWriter(writerPath,true));

        //使用FileWriter的子类方法
        //newLine()方法换行
        bw.write("刘鸿涛");

        //注意关闭节点流
        bw.close();     //此语句会关闭节点流

    }
}
知识点
  • FileWriter对象可以直接创建文件

综合应用

  • 使用BufferedReader 和 BufferedWriter ,完成文件拷贝
注意
//1.BufferedReader 和 BufferedWriter 是按照字符操作
        //2.不要去操作二进制文件【声音,视频,doc,pdf等等】,可能造成文件损坏
package com.taotao.writer_;

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

/**
 * Create By 刘鸿涛
 * 2022/1/28 8:44
 */
public class BufferedCopy_  {
    public static void main(String[] args)throws Exception {
        //1.BufferedReader 和 BufferedWriter 是按照字符操作
        //2.不要去操作二进制文件【声音,视频,doc,pdf等等】,可能造成文件损坏
        String filePath = "d:\\story.txt";
        String targetPath = "d:\\Hello.txt";
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        BufferedWriter bw = new BufferedWriter(new FileWriter(targetPath,true));
        System.out.println("success");
        String line;

        while ((line = br.readLine()) != null){
            //每读取一行就写入
            bw.write(line);
            //因为我们是按行读取,但是上面方法不会换行处理,所以我们需要换行
            bw.newLine();
        }

        if (br != null){
            br.close();
        }
        if (bw != null){
            bw.close();
        }
    }
}

BufferedInputStream 和 BufferedOutputStream

  • 主要用来处理【二进制】文件,也可以用来处理文本文件
  • BufferedInputStream是字节流,在创建BufferedInputStream时,会创建一个内存缓冲区数组

java层 设备节点 java节点类_后端_10

package com.taotao.writer_;

import java.io.*;

/**
 * Create By 刘鸿涛
 * 2022/1/28 9:34
 */
public class BufferedCopy02 {
    public static void main(String[] args)throws IOException {
        String imgPath = "d:\\jing.jpg";
        String targetPath = "d:\\jing02.jpg";
        BufferedInputStream  bi = new BufferedInputStream(new FileInputStream(imgPath));
        BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(targetPath, true));

        byte[] buf = new byte[1024];
        int readLen = 0;
        while((readLen = bi.read(buf)) != -1){
            bo.write(buf, 0, readLen);
        }

        //关闭流
        if (bi != null){
            bi.close();
        }
        if (bo != null){
            bo.close();
        }
    }
}

ObjectInputStream和ObjectOutputStream

序列化和反序列化

  1. 序列化就是在保存数据时,保存数据的值和数据类型
  2. 反序列化就是在恢复数据时,恢复数据的值和数据类型
  3. 需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

Serializable //这是一个标记接口

Externalizeble //这个接口有方法需要实现,因此我们一般实现上面的

java层 设备节点 java节点类_后端_11

java层 设备节点 java节点类_后端_12

java层 设备节点 java节点类_java_13

序列化案例
package com.taotao.outputstream_;


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

/**
 * Create By 刘鸿涛
 * 2022/1/28 10:22
 */
public class ObjectOutputStream_ {
    public static void main(String[] args) throws Exception{
        //序列化后,保存的文件格式,不是纯文本,而是按照他的格式来保存
        String filePath = "d:\\data.dat";
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据到 d:\data.dat
        objectOutputStream.writeInt(100);    //int -> Integer (都实现了Serializable)
//        objectOutputStream.writeInt(100);
        objectOutputStream.writeBoolean(true);  //boolean -> Boolean (实现了 Serializable)
        objectOutputStream.writeChar('a');      //char -> Character (实现了 Serializable)
        objectOutputStream.writeDouble(9.5);;   //double -> Double (实现了 Serializable)
        objectOutputStream.writeUTF("涛涛");      //String    (实现了 Serializable)

        //保存一个dog对象
        objectOutputStream.writeObject(new Dog("汪汪"));

        objectOutputStream.close();
        System.out.println("数据保存完毕(序列化形式)");
    }
}

//如果需要序列化某个类的对象,实现Serializable
class Dog implements Serializable {
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }
}
反序列化案例
package com.taotao.inputstream;

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

/**
 * Create By 刘鸿涛
 * 2022/1/28 12:28
 */
public class ObjectInputStream_ {
    public static void main(String[] args)throws IOException,ClassNotFoundException {
        //指定反序列化的文件
        String filePath = "d:\\data.dat";

        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));

        //读取
        //老师解读
        //1.读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
        //2.否则会出现异常
        System.out.println(objectInputStream.readInt());
        System.out.println(objectInputStream.readBoolean());
        System.out.println(objectInputStream.readChar());
        System.out.println(objectInputStream.readDouble());
        System.out.println(objectInputStream.readUTF());

        Object dog = objectInputStream.readObject();
        System.out.println("运行类型=" + dog.getClass());
        System.out.println("dog信息=" + dog); //底层 Object -> Dog

        //这里是特别重要的地方:当我们的类中有其他方法时,比如toString,我们需要把整个类拿过来
        //1.如果我们希望调用Dog的方法,拷贝到可以引用的位置
        //2.需要我们将Dog类的定义,copy到可以引用的位置

        //关闭流,关闭外层流,底层会自动关闭FileInputStream流
            objectInputStream.close();
    }
}
class Dog implements Serializable {
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }
}
细节
  1. 读写顺序要一致
  2. 要求实现序列化或反序列化对象,需要实现 Serializable
  3. 序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
  4. 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
  5. 序列化对象时,要求里面属性的类型也需要实现序列化接口
public class Dog implements Serializable{
	private Master master = new Master();	//Master也要实现Serializable
}
  1. 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类已经默认实现了序列化

java层 设备节点 java节点类_后端_14

标准输入输出流

介绍

类型

默认设备

System.in 标准输入

InputStream

键盘

System.out 标准输出

PrintStream

显示器

package com.taotao.standard_;

/**
 * Create By 刘鸿涛
 * 2022/1/28 13:56
 */
public class InputAndOutput {
    public static void main(String[] args) {
        //System.in 类 的 public final static InputStream in = null;
        // System.in 编译类型 InputStream
        // System.in 运行类型 BufferedInputStream
        // 表示的是标准输入 键盘
        System.out.println(System.in.getClass());   //BufferedInputStream

        //System.out 类 的 public final static PrintStream out =
        // 编译类型 PrintStream
        // 运行类型 PrintStream
        // 表示标准输出 显示器
        System.out.println(System.out.getClass());  //PrintStream
    }
}

结论

  • 传统方法System.out.println("");是使用out对象将数据输出到显示器
  • 传统方法,Scanner是从标准输入 键盘接收数据

转换流

引出转换流

package com.taotao.transformation;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * Create By 刘鸿涛
 * 2022/1/31 14:44
 * 看一个中文乱码问题
 */
public class CodeQuestion {
    public static void main(String[] args)throws Exception {
        //读取d:\\a.txt 文件到程序
        //思路
        //1.创建字符输入流  bufferedReader[处理流]
        //2.使用 BufferedReader 对象读取a.txt

        String filePath = "d:\\a.txt";
        BufferedReader br = new BufferedReader(new FileReader(filePath));

        String s = br.readLine();
        System.out.println("读取到的内容" + s);

        br.close();
    }
}

如果文件改为非utf-8,并且文件中有中文的话就会出现乱码

java层 设备节点 java节点类_开发语言_15

java层 设备节点 java节点类_java层 设备节点_16

InputStreamReader

java层 设备节点 java节点类_java层 设备节点_17

Reader的子类,可以将InputStream(字节流)包装成(转换成)Reader(字符流)

案例

编程将 字节流FileInputStream包装成(转换成) 字符流InputStreamReader,对文件进行读取(按照utf-8、格式),进而在包装成BufferedReader

package com.taotao.transformation;

import java.io.*;

/**
 * Create By 刘鸿涛
 * 2022/1/31 15:12
 * 演示使用 InputSteamReader 转换成解决中文乱码问题
 * 将字节流FileInputStream 转换成字符流 InputStreamReader,指定编码gbk/uft-8
 */
public class InputSteamReader_ {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\a.txt";
        //解读
        //1.把 FileInputStream 转成 InputStreamReader
        //2.指定编码gbk
        InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
        //3.把 InputStreamReader 传入 BufferedReader
        BufferedReader br = new BufferedReader(isr);
        //4.读取
        String s = br.readLine();
        System.out.println("读取内容=" + s);
        br.close();
    }
}

也可以将第二步和第三步合起来

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),gbk));

OutputStreamWriter

java层 设备节点 java节点类_后端_18

Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)

当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流

可以在使用时指定编码格式(比如 utf-8,gbk,gb2312,ISO8859-1等)

案例

编程将 字节流 FileOutputStream 包装成(转换成)字符流 OutputStreamWriter,对文件进行写入(按照gbk格式,可以指定其他,比如utf-8)

package com.taotao.transformation;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * Create By 刘鸿涛
 * 2022/1/31 15:40
 * 演示OutputStreamWriter使用
 * 把FileOutputStream 字节流,转换成字符流 OutputStreamWriter
 * 指定处理的编码 gbk/utf-8/utf8
 */
public class OutputStreamWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\taotao.txt";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");
        osw.write("hi,涛涛");
        osw.close();
    }
}

打印流

打印流只有输出流,没有输入流

PrintStream

java层 设备节点 java节点类_java层 设备节点_19

案例代码
package com.taotao.printstream;

import java.io.IOException;
import java.io.PrintStream;

/**
 * Create By 刘鸿涛
 * 2022/1/31 18:05
 * 演示PrintStream(字节打印流)
 */
public class PrintStream_ {
    public static void main(String[] args)throws IOException {
        PrintStream out = System.out;
        //在默认情况下 PrintStream 输出数据的位置是 标准输出,即显示器
        out.print("taotoa");
        //因为print底层使用的是write,所以我们可以直接调用write进行打印/输出
        out.write("涛涛".getBytes());
        out.close();

        //我们可以去修改打印流输出的位置/设备
        //1.输出到"d:\\f1.txt"
        //2.“刘洪涛”会输出到"d:\\f1.txt"
        System.setOut(new PrintStream("d:\\f1.txt"));
        System.out.println("刘鸿涛");
    }
}

PrintWriter

java层 设备节点 java节点类_后端_20

案例代码
package com.taotao.transformation;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Create By 刘鸿涛
 * 2022/1/31 18:15
 * 演示 PrintWriter 使用方式
 */
public class PrintWriter_ {
    public static void main(String[] args)throws IOException {
        //标准输出流
//        PrintWriter printWriter = new PrintWriter(System.out);
        PrintWriter printWriter = new PrintWriter(new FileWriter("d:\\f1.txt"));
        printWriter.print("涛涛");

        //flush + 关闭流,才会将数据写入到文件
        printWriter.close();
    }
}

Properties类

基本介绍

1.专门用于读写配置文件的集合类

配置文件的格式:

键 = 值

键 = 值

2.注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String

常见方法

  • load:加载配置文件的键值对到Properties对象
  • list:将数据显示到指定设备
  • getProperty(key):根据键获取值
  • setProperty(key,value):设置键值对到Properties对象
  • store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码

unicode码查询工具

查询工具

需求

如下一个配置文件 mysql.properties

ip = 192.168.0.13
user = root
pwd = 12345

请问编程读取ip 、 user 和 pwd 的值是多少

传统方法

package com.taotao.properties_;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Create By 刘鸿涛
 * 2022/1/31 18:42
 */
public class Properties01 {
    public static void main(String[] args) throws IOException {
        //读取mysql.properties文件,并得到ip,user 和 pwd
        BufferedReader br = new BufferedReader(new FileReader("src\\mysql.properties"));
        String line = "";
//        while ((line = br.readLine())!= null){
//            System.out.println(line);
//        }
        while ((line = br.readLine()) != null){ //循环读取
            String[] split = line.split("=");
            System.out.println(split[0] + "值是:" + split[1]);
        }
        br.close();
    }
}

使用Properties类可以方便实现

package com.taotao.properties_;

import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;

/**
 * Create By 刘鸿涛
 * 2022/2/1 12:38
 */
public class Properties02 {
    public static void main(String[] args) throws IOException {
        //使用Properties 类来读取 mysql.properties 文件

        //1.创建Properties对象
        Properties properties = new Properties();
        //2.加载指定配置文件
        properties.load(new FileReader("src\\mysql.properties"));
        //3.把k-v显示控制台
        properties.list(new PrintStream("d:\\a.txt"));
        //4.根据key 获取对应的值
        String user = properties.getProperty("user");
        String pwd = properties.getProperty("pwd");
        System.out.println("用户名" + user + "\n密码" + pwd);
    }
}

案例Properties类创建修改文件

package com.taotao.properties_;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * Create By 刘鸿涛
 * 2022/2/1 14:17
 */
public class Properties03 {
    public static void main(String[] args) throws IOException {
        //使用Properties 类来创建配置文件,修改配置文件内容

        Properties properties = new Properties();
        //创建
        properties.setProperty("charset","utf8");
        properties.setProperty("user","汤姆");//注意保存时,是中文的 unicode码值
        properties.setProperty("pwd","abc111");

        //将k-v 存储文件中即可、     FileOutputStream字节流
        properties.store(new FileOutputStream("src\\mysql2.properties"),null);
        System.out.println("保存配置文件成功");

        //当然我们可以通过key轻松修改value,比如
        properties.setProperty("user","jack");
        //此时他的user就会被替换为jack
    }
}