023Java基础之IO

1、IO 流原理及流的分类

1.1、Java IO 流原理

(1)I/O是Input和Output的缩写,I/O技术是非常使用的技术,用于处理数据传输,如读写文件,网络通讯等
(2)Java程序中,对于数据的输入/输出操作以流(Stream)的方式进行
(3)java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并提供方法输入或输出数据
在这里插入图片描述
在这里插入图片描述

1.2、流的分类

(1)按操作数据单位不同分为:字节流(8bit),用来操作二进制文件、字符流(以字符为单位),用来操作文本文件
(2)按数据流的流向不同分为:输入流、输出流
(3)按流的角色不同分为:节点流、处理流(也叫包装流)
在这里插入图片描述
这四个基类都是abstract的,不能直接实例化,在使用时只能通过其子类来创建对象
在这里插入图片描述

在这里插入图片描述

1.3、文件和流的理解

流是文件传输的载体

2、InputStream 字节输入流

InputStream 抽象类是所有类字节输入流的超类,其常用的子类有
(1)FileInputStream :文件输入流
(2)BufferedInputStream :缓冲字节输入流
(3)ObjectInputStream :对象字节输入流
在这里插入图片描述

2.1、FileInputStream
package com.francis.inputstream;

import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author Francis
 * @create 2021-11-18 20:50
 */
public class FileInputStream_ {
    //使用单个字符方式读取文件内容
    @Test
    public void readFile01(){
        String  filePath = "f:\\hello.txt";
        int readData= 0;
        StringBuffer stringBuffer = new StringBuffer();
        FileInputStream fileInputStream=null;
        try {
             fileInputStream = new FileInputStream(filePath);
            //read方法从输入流中读取一个字节的数据,如果没有输入可用,此方法将阻止,
            //read方法的返回值为char字符对应的ascII码,如果返回-1,表示读取完毕
            while ((readData=fileInputStream.read())!=-1){
                //将ascII转成字符
                char chr = ((char) readData);
                stringBuffer.append(chr);
                System.out.println(chr);
            }
            System.out.println(stringBuffer);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
        //输入流作为系统的资源,一定要记得关闭
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //使用byte数组方式读取文件内容read(byte[] b)
    @Test
    public void readFile02(){
        String  filePath = "f:\\hello.txt";
        int readLen= 0;
        //一次性读取8个字节
        byte[] buff= new byte[8];
        StringBuffer stringBuffer = new StringBuffer();
        FileInputStream fileInputStream=null;
        try {
             fileInputStream = new FileInputStream(filePath);
            //该方法一次性读取最多buff.length的数据,返回值为每次实际读取到的字节数,如果到达末尾,返回-1
            while ((readLen=fileInputStream.read(buff))!=-1){
                //这里需要注意,以后读取的时候有字符的话buff里的字符会依次被替换,如果没有字符,将保留上一次读取的字符
                //所以不能用buff.length来构建String
                String str = new String(buff, 0, readLen);
                System.out.println(str);
                stringBuffer.append(str);
            }
            System.out.println(stringBuffer);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
        //输入流作为系统的资源,一定要记得关闭
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3、OutputStream

在这里插入图片描述

3.1、FileOutputStream 字节输出流
package com.francis.outputstream;

import org.junit.jupiter.api.Test;

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

/**
 * @author Francis
 * @create 2021-11-18 21:51
 */
public class FileOutputStream_ {
    /**
     * 将数据写入文件
     * 如果该文件不存在,则创建该文件
     */
    @Test
    public void fileWrite(){
        String filePath = "f:\\write1.txt";
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream= new FileOutputStream(filePath);
            //写入一个字节
            //fileOutputStream.write('F');

            //写入字符串
            String hello = "hello Beijing";
            byte[] buff = hello.getBytes();
            fileOutputStream.write(buff);
            /*
            write(byte[] b,int off,int len),方法,指定从byte数组中off位置开始,写入len长度个字节
             */
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 上面的方式写入到文件会覆盖原来文件的内容,如果想要对已存在文件进行追加操作
     * 可以调用FileOutputStream的另外一个构造器来使该字节输出流完成该功能
     */
    @Test
    public void fileWriteAppend(){
        String filePath = "f:\\write1.txt";
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream= new FileOutputStream(filePath,true);
            //写入一个字节
            //fileOutputStream.write('F');

            //写入字符串
            String hello = "hello Beijing";
            byte[] buff = hello.getBytes();
            fileOutputStream.write(buff);
            /*
            write(byte[] b,int off,int len),方法,指定从byte数组中off位置开始,写入len长度个字节
             */
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

输入流输出流配合案例:文件拷贝

package com.francis.outputstream;

import org.junit.jupiter.api.Test;

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

/**
 * @author Francis
 * @create 2021-11-18 22:29
 */
public class FileCopy {
    @Test
    public  void copyJpg(){
        String srcFile="f:\\1.jpg";
        String destFile="f:\\3.jpg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        byte[] buff = new byte[1024];
        int dataLen = 0;
        int times = 0;
        try {
            fileInputStream=new FileInputStream(srcFile);
            fileOutputStream = new FileOutputStream(destFile,true);
            while ((dataLen= fileInputStream.read(buff))!=-1){
                times++;
                System.out.println(times);
                fileOutputStream.write(buff,0,dataLen);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
    }
}

4、Reader

在这里插入图片描述

4.1、FileReader

相关方法
(1)构造器new FileReader(File/String)
(2)read,每次读取单个字符,返回该字符,如果到文件末尾,返回-1
(3)read(char[]) 批量读取多个字符数组,返回读取到的字符数,如果到达文件末尾,返回-1
相关API
(1)new String(char[]) 将char[]数组转成String
(2)new String (char[],off,len)将char[]的指定部分转成String

package com.francis.reader;

import org.junit.jupiter.api.Test;

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

/**
 * @author Francis
 * @create 2021-11-19 21:10
 */
public class FileReader_ {
    //每次读取一个字符
    @Test
    public void readFile1() {
        String filePath = "f:\\story.txt";
        FileReader fileReader = null;
        int data =0;
        try {
            fileReader = new FileReader(filePath);
            while((data=fileReader.read())!=-1){
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //每次读取一个字符数组
    @Test
    public void readFile2() {
        String filePath = "f:\\story.txt";
        FileReader fileReader = null;
        char[] buff = new char[8];
        int dataLen =0;
        try {
            fileReader = new FileReader(filePath);
            System.out.println("使用char数组读取");
            while((dataLen=fileReader.read(buff))!=-1){
                System.out.print(new String(buff,0,dataLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5、Writer

在这里插入图片描述

5.1、FileWriter

相关方法
(1)new FileWriter(File/String),覆盖模式,相当于流的指针在首端
(2)new FileWriter(File/String,true)追加模式,相当于流的指针在末端
(3)write(),写入单个字符,
(4)write(char[] ) 写入指定字符数组
(5)write(char[],off,len)写入指定数组的指定部分
(6)write(String) 写入整个字符串
(7)write(String,off,len)写入字符串的指定部分
相关API
(1)String类:toCharArray(),将String转换成char[]
注意
FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定文件

package com.francis.writer;

import org.junit.jupiter.api.Test;

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

/**
 * @author Francis
 * @create 2021-11-19 22:05
 */
public class FileWriter_ {
    /**
     * 单个字符写出
     */
    @Test
    public void writeFile1() {
        String filePath = "f:\\note.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            fileWriter.write('H');
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 写入字符数组
     */
    @Test
    public void writeFile2() {
        String filePath = "f:\\note.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            char[] chars = "hello world2".toCharArray();
            fileWriter.write(chars);
            fileWriter.flush();
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 写入字符数组的指定长度字符
     */
    @Test
    public void writeFile3() {
        String filePath = "f:\\note.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            char[] chars = "hello world3".toCharArray();
            fileWriter.write(chars, 0, 5);

            fileWriter.flush();
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 写入整个字符串
     */
    @Test
    public void writeFile4() {
        String filePath = "f:\\note.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            String str = "hello world4";
            fileWriter.write(str);
            fileWriter.flush();
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 写入指定字符串的指定长度
     */
    @Test
    public void writeFile5() {
        String filePath = "f:\\note.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            String str = "hello world5";
            fileWriter.write(str, 0, 5);
            fileWriter.flush();
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 追加模式写入文件
     */
    @Test
    public void writeFile6() {
        String filePath = "f:\\note.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath, true);
            String str = "hello world6";
            fileWriter.write(str);
            fileWriter.flush();
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

6、节点流和处理流

6.1、基本介绍

(1)节点流可以从一个特定的数据源读取数据,如FileReader、FileWriter
在这里插入图片描述
(2)处理流也叫包装流,是“连接”已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferReader、BufferWriter
在这里插入图片描述
在这里插入图片描述

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

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

6.3、处理流-BufferedReader 和 BufferedWriter

BufferedReader 和 BufferedWriter属于字符处理流,是按照字符来读取数据的,关闭处理流时,只需要关闭外层流即可。这是因为在关闭处理流时,底层会调用节点流的close方法。

package com.francis.writer;

import org.junit.jupiter.api.Test;

import java.io.*;

/**
 * @author Francis
 * @create 2021-11-23 23:12
 */
public class BufferedCopy {
    @Test
    public void copy(){
        String srcFile = "f:\\story.txt";
        String destFile = "f:\\story2.txt";
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(srcFile));
            bufferedWriter= new BufferedWriter(new FileWriter(destFile,true));
            String line ;
            while ((line=bufferedReader.readLine())!=null){
                bufferedWriter.write(line);
                System.out.println(line);
                bufferedWriter.newLine();
            }
            //与fileWriter一样,需要flush或者close文件才会真正的被写入内容
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
                //bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
6.4、处理流-BufferedInputStream 和 BufferedOutputStream

BufferedInputStream 是字节处理流,在创建BufferedInputStream 时,会创建一个内存缓冲区数组;BufferedOutputStream也是字节处理流,可以将多个字节写入到底层输出流中,而不必对每次字节写入调用底层系统。

package com.francis.outputstream;

import org.junit.jupiter.api.Test;

import java.io.*;

/**
 * 拷贝二进制文件
 *
 * @author Francis
 * @create 2021-11-23 23:42
 */
public class BufferedCopy {
    @Test
    public void copy() {
        String srcFile = "f:\\1.avi";
        String destFile = "f:\\2.avi";
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFile));
            byte[] buffer = new byte[1024];
            int readLen= 0;
            while ((readLen =bufferedInputStream.read(buffer))!=-1){
                bufferedOutputStream.write(buffer, 0, readLen);

            }
            System.out.println("拷贝成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bufferedInputStream!=null){
                    bufferedInputStream.close();

                }
                if(bufferedOutputStream!=null){
                    bufferedOutputStream.close();

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
6.5、对象处理流-ObjectInputStream 和 ObjectOutputStream

当我们需要把一个数据及其类型保存到文件中,并且可以从文件中回复该数据及其类型,这时我们需要使用到对象流
序列化和反序列化
(1)序列化就是在保存数据时,不仅保存数据本身,还要保存数据的类型
(2)反序列化就是在恢复数据时,不仅要恢复数据的值,还要恢复数据的类型
(3)需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一
①Serializable,这是一个标记接口,没有方法需要实现
②Externalizable,该接口有一个方法需要实现,因此我们一般实现上面的Serializable接口
对象流介绍
功能:提供了对基本类型或对象类型的序列化和反序列化的方法
ObjectOutputStream 提供 序列化功能
在这里插入图片描述

package com.francis.outputstream;

import org.junit.jupiter.api.Test;

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

/**
 * 演示ObjectOutputStream的使用
 * @author Francis
 * @create 2021-11-24 20:09
 */
public class ObjectOutputStream_ {
    @Test
    public void writeObject() throws IOException {
        //这里的文件后缀名是随便写的,保存之后的文件并不是纯文本文件,而是有特殊的格式,就算写成txt也不是文本文件
        //String filePath = "f:\\object.txt";
        String filePath = "f:\\object.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
        //基本数据类型会自动装箱,并且根据方法的名字,就可以推测,保存的类型是什么
        oos.writeInt(100);
        oos.writeBoolean(true);
        oos.writeChar('a');
        oos.writeDouble(2.1);
        oos.writeFloat(1.2f);
        oos.writeUTF("我爱你中国");
        Dog dog1 = new Dog("黄色","小黄",1,"中国");
        Dog dog2 = new Dog("黑色","小黑",2,"中国");
        //如果对象没有实现序列化接口,会抛异常
        oos.writeObject(dog1);
        oos.writeObject(dog2);
        oos.close();

    }
}

package com.francis.outputstream;

import java.io.Serializable;

/**
 * @author Francis
 * @create 2021-11-24 20:56
 */
public class Dog implements Serializable {
    //提高兼容性,当某天新增了一个属性,jvm不会认为是新的类,而是升级版
    private static final long serialVersionUID = 1L;
    //这两个属性不会被序列化,可以在反序列化时输出验证
    private static  String nation ;
    private  transient  String color;
    private String name;
    private int age;

    public Dog(String color, String name, int age,String nation) {
        this.color = color;
        this.name = name;
        this.age = age;
        this.nation = nation;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    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 "Dog{" +
                "color='" + color + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", nation=" + nation +
                '}';
    }
}

ObjectInputStream 提供 反序列化功能
在这里插入图片描述

package com.francis.inputstream;

import com.francis.outputstream.Dog;
import org.junit.jupiter.api.Test;

import java.io.*;

/**
 * @author Francis
 * @create 2021-11-24 20:31
 */
public class ObjectInputStream_ {
    @Test
    public void parseObject() throws IOException, ClassNotFoundException {
        String filePath = "f:\\object.dat";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        //反序列化的顺序要跟序列化的顺序保持一致
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readFloat());
        System.out.println(ois.readUTF());
        //读取对象时可能存在类型转换异常
        Dog dog1 =(Dog) ois.readObject();
        Dog dog2 =(Dog) ois.readObject();
        System.out.println(dog2.getName());
        //如果我们需要调用dog的方法,我们就需要向下转型,得保证在反序列化的
        //环境下也存在Dog类,并且包名也要相同,特别是客户端和服务端的时候,并不在同一个系统下时
        //要注意,这里我们就直接引用output包下的即可
        System.out.println(dog1);
        System.out.println(dog2);
        ois.close();

    }
}

注意事项和细节说明
(1)在反序列化时,顺序要与序列化时保持一致
(2)要求反序列化和序列化的对象需要实现两个序列化接口的其中一个,一般我们实现Serializable
(3)序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性private static final long serialVersionUID = 1L;
(4)序列化对象时,默认将对象里的所有属性都进行序列化,但除了static或transient修饰的成员
(5)序列化对象时,要求里面属性的类型也需要实现序列化接口
(6)序列化具备可继承性,也就是某类已经实现了序列化,则它的所有子类也默认实现了序列化
在这里插入图片描述

6.6、标准输入输出流

System.in 标准输入流 默认设备时键盘
System.out 标准输出流 默认设备时显示器

package com.francis.standard;

import org.junit.jupiter.api.Test;

import java.util.Scanner;

/**
 * @author Francis
 * @create 2021-11-24 22:05
 */
public class InputAndOutput {
    public static void main(String[] args) {
        //System.in的编译类型是public final static InputStream in = null;
        //System.ind的运行类型是BufferedInputStream,标准输入表示的就是键盘
        System.out.println(System.in.getClass());
        //System.out的编译类型是public final static PrintStream out = null;
        //System.out的运行类型PrintStream,标准输出表示的就是输出到键盘上
        System.out.println(System.out.getClass());
        //scanner每次回去处理流bufferedInputStream的缓冲区中去获取数据
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入内容");
        String next = scanner.next();
        System.out.println(next);
    }
}
6.7、转换流处理流-InputStreamReader 和 OutputStreamWriter

乱码问题

package com.francis.transformation;

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

/**
 * @author Francis
 * @create 2021-11-24 22:25
 */
public class CodeQuestion {
    public static void main(String[] args) throws IOException {
        //读取 f:\\a.txt 文件到程序
//1. 创建字符输入流 BufferedReader [处理流]
//2. 使用 BufferedReader 对象读取 a.txt
//3. 默认情况下,读取文件是按照 utf-8 编码
        String filePath = "f:\\a.txt";
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        String s = br.readLine();
        //编码格式不统一,会出现中文乱码
        System.out.println("读取到的内容: " + s);
        br.close();
    //InputStreamReader
    //OutputStreamWriter
    }

}

(1)InputStreamReader 是Reader的子类,可以将InputStream(字节流)转换成Reader(字符流)
(2)OutputStreamWriter是Writer的子类,可以将OutputStream(字节流)转换成Writer(字符流)
(3)当处理纯文本数据时,使用字符流效率更高,并且可以有效解决中文乱码问题,所以建议将字节流转换成字符流
(4)字符装换流可以在使用时指定编码格式(utf-8,gbk,gb2312,ISO8859-1)

package com.francis.transformation;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author Francis
 * @create 2021-11-24 22:52
 */
public class InputStreamReader_ {
    public static void main(String[] args) throws IOException {
        String filePath = "f:\\a.txt";
//1. 把 FileInputStream 转成 InputStreamReader
//2. 指定编码 UTF-8
//InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
//3. 把 InputStreamReader 传入 BufferedReader
//BufferedReader br = new BufferedReader(isr);
//将 2 和 3 合在一起
        BufferedReader br = new BufferedReader(new InputStreamReader(
                new FileInputStream(filePath), "UTF-8"));
//4. 读取
        String s = br.readLine();
        System.out.println(s);
//5. 关闭外层流
        br.close();
    }
}
6.8、打印处理流-PrintStream 和 PrintWriter

在这里插入图片描述

package com.francis.printstream;

import java.io.PrintStream;

/**
 * @author Francis
 * @create 2021-11-25 22:35
 */
public class PrintStream_ {
    public static void main(String[] args) throws Exception {
        PrintStream out = System.out;
//在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
/*
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
*/
        out.print("hello,world");
//因为 print 底层使用的是 write , 所以我们可以直接调用 write 进行打印/输出
        out.write("同一个世界,同一个梦想".getBytes());
        out.close();
//我们可以去修改打印流输出的位置/设备
//1. 输出修改成到 "f:\\f1.txt"
//2. "hello, 韩顺平教育~" 就会输出到f:\f1.txt
//3. public static void setOut(PrintStream out) {
// checkIO();
// setOut0(out); // native 方法,修改了 out
// }
        System.setOut(new PrintStream("f:\\f1.txt"));
        System.out.println("北京欢迎你");
    }
}


在这里插入图片描述

package com.francis.printstream;

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

/**
 * 演示PrintWriter的使用
 *
 * @author Francis
 * @create 2021-11-25 22:58
 */
public class PrintWriter_ {
    public static void main(String[] args) throws  Exception{
        //PrintWriter printWriter = new PrintWriter(System.out);
        PrintWriter printWriter = new PrintWriter(new FileWriter("f:\\f2.txt"));
        printWriter.print("hi, 北京你好~~~~");
        printWriter.close();//flush + 关闭流, 才会将数据写入到文件..
    }
}

7、Properties 类

7.1、基本介绍

(1)专门用于读取配置文件的集合类
配置文件的格式:
键=值
(2)注意,键值对不需要有空格,值不需要使用引号默认类型是String
(3)Properties的常见方法
①load加载配置文件的键值对到Properties对象
②将数据显示到指定设备
③getPRoperty(key)根据键获取值
④store将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果还有中文,保存的是unicode码

package com.francis.properties;

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

/**
 * @author Francis
 * @create 2021-11-25 23:51
 */
public class Properties02 {
    public static void main(String[] args) throws IOException {
//使用 Properties 类来读取 mysql.properties 文件
        String filePath = "F:\\DevWorkspace\\code\\exercises\\JavaSE" +
                "\\chapter19\\src\\mysql.properties";
//1. 创建 Properties 对象
        Properties properties = new Properties();
//2. 加载指定配置文件
        properties.load(new FileReader(filePath));
//3. 把 k-v 显示控制台
        properties.list(System.out);
//4. 根据 key 获取对应的值
        String user = properties.getProperty("username");
        String pwd = properties.getProperty("password");
        System.out.println("用户名=" + user);
        System.out.println("密码是=" + pwd);
    }
}
package com.francis.properties;

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

/**
 * @author Francis
 * @create 2021-11-25 23:56
 */
public class Properties03 {
    public static void main(String[] args) throws IOException {
//使用 Properties 类来创建 配置文件, 修改配置文件内容
        Properties properties = new Properties();
//创建
//1.如果该文件没有 key 就是创建
//2.如果该文件有 key ,就是修改
/*
Properties 父类是 Hashtable , 底层就是 Hashtable 核心方法
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;//如果 key 存在,就替换
return old;
}
}
addEntry(hash, key, value, index);//如果是新 k, 就 addEntry
return null;
}
*/
        properties.setProperty("charset", "utf8");
        properties.setProperty("user", "汤姆");//注意保存时,是中文的 unicode 码值
        properties.setProperty("pwd", "888888");
//将 k-v 存储文件中即可
        properties.store(new FileOutputStream("F:\\DevWorkspace\\code\\exercises\\JavaSE" +
                        "\\chapter19\\src\\mysql.properties"),
                null);
        System.out.println("保存配置文件成功~");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值