IO流使用说明

本文详细介绍了Java中的IO流,包括缓存流的性能优化原理及实例,转换流用于处理不同编码文件的方法,对象序列化与反序列化的步骤,打印流的使用如PrintStream和PrintWriter,以及Properties对象在属性配置中的应用。此外,还提及了Apache Commons IO的FileUtils工具类及其常用方法。
摘要由CSDN通过智能技术生成

1、缓存流

缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能
字节缓冲流
字节缓冲输入流: BufferedInputStream
字节缓冲输出流: BufferedOutputStream
字符缓冲流
字符缓冲输入流: BufferedReader
字符缓冲输出流: BufferedWriter

字节缓冲流性能优化原理:

字节缓冲输入流 自带了 8KB缓冲池 以后我们直接从缓冲池读取数据,所以性能较好
字节缓冲输出流 自带了 8KB缓冲池 数据就直接写入到缓冲池中去, 写数据 性能极高了
字节缓冲输入流: BufferedInputStream ,提高字节输入流读取数据的性能,读写功能上并无变化。
字节缓冲输出流: BufferedOutputStream ,提高字节输出流读取数据的性能,读写功能上并无变化。

构造器

说明

public BufferedInputStream​(InputStream is)

可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能

public BufferedOutputStream​(OutputStream os)

可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能

import java.io.*;

/**
    目标:使用字节缓冲流完成数据的读写操作。
 */
public class ByteBufferDemo {
    public static void main(String[] args) {

        try (
                // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
                // 1、创建一个字节输入流管道与原视频接通
                InputStream is = new FileInputStream("D:\\resources\\newmeinv.jpeg");
                // a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis = new BufferedInputStream(is);
                // 2、创建一个字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream("D:\\resources\\newmeinv222.jpeg");
                // b.把字节输出流管道包装成高级的缓冲字节输出流管道
                OutputStream bos = new BufferedOutputStream(os);

        ) {

            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer, 0 , len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e){
            e.printStackTrace();
        }

    }
}

分别使用不同的方式复制大视频观察性能情况

需求

分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时。

分析

使用低级的字节流按照一个一个字节的形式复制文件。
使用低级的字节流按照一个一个字节数组的形式复制文件。
使用高级的缓冲字节流按照一个一个字节的形式复制文件。
使用高级的缓冲字节流按照一个一个字节数组的形式复制文件。
import java.io.*;

/**
    目标:利用字节流的复制统计各种写法形式下缓冲流的性能执行情况。

    复制流:
        (1)使用低级的字节流按照一个一个字节的形式复制文件。
        (2)使用低级的字节流按照一个一个字节数组的形式复制文件。
        (3)使用高级的缓冲字节流按照一个一个字节的形式复制文件。
        (4)使用高级的缓冲字节流按照一个一个字节数组的形式复制文件。

    源文件:C:\course\3-视频\18、IO流-文件字节输出流FileOutputStream写字节数据出去.avi
    目标文件:C:\course\

    小结:
        使用高级的缓冲字节流按照一个一个字节数组的形式复制文件,性能好,建议开发使用!
 */
public class ByteBufferTimeDemo {
    private static final String SRC_FILE = "D:\\course\\基础加强\\day08-日志框架、阶段项目\\视频\\14、用户购票功能.avi";
    private static final String DEST_FILE = "D:\\course\\";

    public static void main(String[] args) {
        // copy01(); // 使用低级的字节流按照一个一个字节的形式复制文件:慢的让人简直无法忍受。直接被淘汰。
        copy02(); // 使用低级的字节流按照一个一个字节数组的形式复制文件: 比较慢,但是还是可以忍受的!
        // copy03(); // 缓冲流一个一个字节复制:很慢,不建议使用。
        copy04(); // 缓冲流一个一个字节数组复制:飞快,简直太完美了(推荐使用)
    }

    private static void copy04() {
        long startTime = System.currentTimeMillis();
        try (
                // 1、创建低级的字节输入流与源文件接通
                InputStream is = new FileInputStream(SRC_FILE);
                // a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis = new BufferedInputStream(is);
                // 2、创建低级的字节输出流与目标文件接通
                OutputStream os = new FileOutputStream(DEST_FILE + "video4.avi");
                // b.把字节输出流管道包装成高级的缓冲字节输出流管道
                OutputStream bos = new BufferedOutputStream(os);
        ) {

            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer, 0 , len);
            }

        } catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用缓冲的字节流按照一个一个字节数组的形式复制文件耗时:" + (endTime - startTime)/1000.0 + "s");
    }



    private static void copy03() {
        long startTime = System.currentTimeMillis();
        try (
                // 1、创建低级的字节输入流与源文件接通
                InputStream is = new FileInputStream(SRC_FILE);
                // a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis = new BufferedInputStream(is);
                // 2、创建低级的字节输出流与目标文件接通
                OutputStream os = new FileOutputStream(DEST_FILE + "video3.avi");
                // b.把字节输出流管道包装成高级的缓冲字节输出流管道
                OutputStream bos = new BufferedOutputStream(os);
        ){

            // 3、定义一个变量记录每次读取的字节(一个一个字节的复制)
            int b;
            while ((b = bis.read()) != -1){
                bos.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用缓冲的字节流按照一个一个字节的形式复制文件耗时:" + (endTime - startTime)/1000.0 + "s");
    }


    private static void copy02() {
        long startTime = System.currentTimeMillis();
        try (
                // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
                // 1、创建一个字节输入流管道与原视频接通
                InputStream is = new FileInputStream(SRC_FILE);
                // 2、创建一个字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream(DEST_FILE + "video2.avi")
        ) {

            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用低级的字节流按照一个一个字节数组的形式复制文件耗时:" + (endTime - startTime)/1000.0 + "s");
    }

    /**
      使用低级的字节流按照一个一个字节的形式复制文件
     */
    private static void copy01() {
        long startTime = System.currentTimeMillis();
        try (
                // 1、创建低级的字节输入流与源文件接通
                InputStream is = new FileInputStream(SRC_FILE);
                // 2、创建低级的字节输出流与目标文件接通
                OutputStream os = new FileOutputStream(DEST_FILE + "video1.avi")
                ){

            // 3、定义一个变量记录每次读取的字节(一个一个字节的复制)
            int b;
            while ((b = is.read()) != -1){
                os.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用低级的字节流按照一个一个字节的形式复制文件耗时:" + (endTime - startTime)/1000.0 + "s");
    }

}

字符缓冲输入流

字符缓冲输入流: BufferedReader
作用:提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。

构造器

说明

public BufferedReader​(Reader r)

可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道,从而提高字符输入流读数据的性能

字符缓冲输入流新增功能

方法

说明

public String readLine()

读取一行数据返回,如果读取没有完毕,无行可读返回null

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

/**
    目标:学会使用缓冲字符输入流提高字符输入流的性能,新增了按照行读取的方法(经典代码)
 */
public class BufferedReaderDemo1 {
    public static void main(String[] args) {
        try (
                // 1、创建一个文件字符输入流与源文件接通。
                Reader fr = new FileReader("io-app2/src/data01.txt");
                // a、把低级的字符输入流包装成高级的缓冲字符输入流。
                BufferedReader br = new BufferedReader(fr);
                ){

            // 2、用循环,每次读取一个字符数组的数据。  1024 + 1024 + 8
//            char[] buffer = new char[1024]; // 1K字符
//            int len;
//            while ((len = br.read(buffer)) != -1) {
//                String rs = new String(buffer, 0, len);
//                System.out.print(rs);
//            }

              String line;
              while ((line = br.readLine()) != null){
                  System.out.println(line);
              }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符缓冲输出流

字符缓冲输出流: BufferedWriter
作用:提高字符输出流写取数据的性能,除此之外多了换行功能

构造器

说明

public BufferedWriter​(Writer w)

可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能

字符缓冲输出流新增功能

方法

说明

public void newLine()

换行操作

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

/**
     目标:缓冲字符输出流的使用,学会它多出来的一个功能:newLine();
 */
public class BufferedWriterDemo2 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个字符输出流管道与目标文件接通
        Writer fw = new FileWriter("io-app2/src/out02.txt"); // 覆盖管道,每次启动都会清空文件之前的数据
       //Writer fw = new FileWriter("io-app2/src/out02.txt", true); // 追加数据
        BufferedWriter bw = new BufferedWriter(fw);

//      a.public void write(int c):写一个字符出去
        bw.write(98);
        bw.write('a');
        bw.write('徐'); // 不会出问题了
        bw.newLine(); // bw.write("\r\n"); // 换行

//       b.public void write(String c)写一个字符串出去
        bw.write("abc我是中国人");
        bw.newLine(); // bw.write("\r\n"); // 换行


//       c.public void write(char[] buffer):写一个字符数组出去
        char[] chars = "abc我是中国人".toCharArray();
        bw.write(chars);
        bw.newLine(); // bw.write("\r\n"); // 换行


//       d.public void write(String c ,int pos ,int len):写字符串的一部分出去
        bw.write("abc我是中国人", 0, 5);
        bw.newLine(); // bw.write("\r\n"); // 换行

//       e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
        bw.write(chars, 3, 5);
        bw.newLine(); // bw.write("\r\n"); // 换行


        // fw.flush();// 刷新后流可以继续使用
        bw.close(); // 关闭包含刷线,关闭后流不能使用

    }
}

拷贝出师表到另一个文件,恢复顺序

需求:把《出师表》的文章顺序进行恢复到一个新文件中

分析:

定义一个缓存字符输入流管道与源文件接通。
定义一个List集合存储读取的每行数据。
定义一个循环按照行读取数据,存入到List集合中去。
对List集合中的每行数据按照首字符编号升序排序。
定义一个缓存字符输出管道与目标文件接通。
遍历List集合中的每个元素,用缓冲输出管道写出并换行。
import java.io.*;
import java.util.*;

/**
   目标:完成出师表顺序的恢复,并存入到另一个新文件中去。
 */
public class BufferedCharTest3 {
    public static void main(String[] args) {
        try(
                // 1、创建缓冲字符输入流管道与源文件接通
                BufferedReader br = new BufferedReader(new FileReader("day20/src/csb.txt"));

                // 5、定义缓冲字符输出管道与目标文件接通
                BufferedWriter bw = new BufferedWriter(new FileWriter("day20/src/new.txt"));
                ) {

            // 2、定义一个List集合存储每行内容
            List<String> data = new ArrayList<>();
            // 3、定义循环,按照行读取文章
            String line;
            while ((line = br.readLine()) != null){
                data.add(line);
            }
            System.out.println(data);

            // 4、排序
            // 自定义排序规则
            List<String> sizes = new ArrayList<>();
            Collections.addAll(sizes, "一","二","三","四","五","陆","柒","八","九","十","十一");

            Collections.sort(data, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    // o1   八.,....
                    // o2   柒.,....
                    return sizes.indexOf(o1.substring(0, o1.indexOf(".")))
                            - sizes.indexOf(o2.substring(0, o2.indexOf(".")));
                }
            });
            System.out.println(data);

            // 6、遍历集合中的每行文章写出去,且要换行
            for (String datum : data) {
                bw.write(datum);
                bw.newLine(); // 换行
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2、转换流

使用相同编码读取不同编码的文件内容

需求:分别使用如下两种方式读取文件内容

代码编码是 UTF-8 ,文件编码也是 UTF-8 ,使用字符流读取观察输出的中文字符结果。
代码编码是 UTF-8 ,文件编码使用 GBK ,使用字符流读取观察输出的中文字符结果
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

/**
   演示一下代码编码与文件编码相同和不同的情况
 */
public class CharSetTest00 {
    public static void main(String[] args) {
        try (
                // 代码:UTF-8 文件 UTF-8 不会乱码
                // 1、创建一个文件字符输入流与源文件接通。
                // Reader fr = new FileReader("io-app2/src/data01.txt");


                // 代码:UTF-8 文件 GBK  乱码.     abc 我   爱 你中国
                //                                  oo  oo
                Reader fr = new FileReader("D:\\resources\\data.txt");
                // a、把低级的字符输入流包装成高级的缓冲字符输入流。
                BufferedReader br = new BufferedReader(fr);
        ){


            String line;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符输入转换流

字符输入转换流: InputStreamReader 可以把原始的字节流按照指定编码转换成字符输入流

构造器

说明

public InputStreamReader(InputStream is)

可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用,与默认的FileReader一样。

public InputStreamReader(InputStream is String charset)

可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中的字符就不乱码了(重点)

import java.io.*;

/**
     目标:字符输入转换流InputStreamReader的使用。

             字节流                                     字符流
     字节输入流               字节输出流              字符输入流            字符输出流
     InputStream             OutputStream          Reader               Writer   (抽象类)
     FileInputStream         FileOutputStream      FileReader           FileWriter(实现类)
     BufferedInputStream     BufferedOutputStream  BufferedReader       BufferedWriter(实现类,缓冲流)
                                                   InputStreamReader    OutputStreamWriter
     字符输入转换流InputStreamReader:
          -- 作用:可以解决字符流读取不同编码乱码的问题。
                  也可以把原始的字节流按照指定编码转换成字符输入流

          -- 构造器:
                public InputStreamReader(InputStream is):可以使用当前代码默认编码转换成字符流,几乎不用!
                public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)

     小结:
        字符输入转换流InputStreamReader:作用:可以解决字符流读取不同编码乱码的问题。
        public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)
 */
public class InputStreamReaderDemo01 {
    public static void main(String[] args) throws Exception {
        // 代码UTF-8   文件 GBK  "D:\\resources\\data.txt"
        // 1、提取GBK文件的原始字节流。   abc 我
        //                            ooo oo
        InputStream is = new FileInputStream("D:\\resources\\data.txt");
        // 2、把原始字节流转换成字符输入流
        // Reader isr = new InputStreamReader(is); // 默认以UTF-8的方式转换成字符流。 还是会乱码的  跟直接使用FileReader是一样的
        Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK编码转换成字符输入流  完美的解决了乱码问题

        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}

字符输出转换流

字符输入转换流: OutputStreamWriter 可以 把字节输出流 按照指定编码转换成字符输

构造器

说明

public OutputStreamWriter(OutputStream os)

可以把原始的字节输出流按照代码默认编码转换成字符输。几乎不用。

public OutputStreamWriter(OutputStream osString charset)

可以把原始的字节输出流按照指定编码转换成字符输(重点)

import java.io.*;
import java.nio.Buffer;

/**
     目标:字符输出转换OutputStreamWriter流的使用。

                字节流                                         字符流
     字节输入流               字节输出流              字符输入流            字符输出流
     InputStream             OutputStream          Reader               Writer   (抽象类)
     FileInputStream         FileOutputStream      FileReader           FileWriter(实现类)
     BufferedInputStream     BufferedOutputStream  BufferedReader       BufferedWriter(实现类,缓冲流)
                                                   InputStreamReader    OutputStreamWriter

     字符输出转换流:OutputStreamWriter
           -- 作用:可以指定编码把字节输出流转换成字符输出流。
                   可以指定写出去的字符的编码。
           -- 构造器:
                public OutputStreamWriter(OutputStream os) :   用当前默认编码UTF-8把字节输出流转换成字符输出流
                public OutputStreamWriter(OutputStream os , String charset):指定编码把字节输出流转换成字符输出流
     小结:
        字符输出转换流OutputStreamWriter可以指定编码把字节输出流转换成字符输出流。
        从而实现指定写出去的字符编码!
 */
public class OutputStreamWriterDemo02 {
    public static void main(String[] args) throws Exception {
        // 1、定义一个字节输出流
        OutputStream os = new FileOutputStream("io-app2/src/out03.txt");

        // 2、把原始的字节输出流转换成字符输出流
        // Writer osw = new OutputStreamWriter(os); // 以默认的UTF-8写字符出去 跟直接写FileWriter一样
        Writer osw = new OutputStreamWriter(os , "GBK"); // 指定GBK的方式写字符出去

        // 3、把低级的字符输出流包装成高级的缓冲字符输出流。
        BufferedWriter bw = new BufferedWriter(osw);

        bw.write("我爱中国1~~");
        bw.write("我爱中国2~~");
        bw.write("我爱中国3~~");

        bw.close();
    }
}

3、序列化对象

对象序列化

作用:以内存为基准, 把内存中的对象存储到磁盘文件中去,称为对象序列化。
使用到的流是对象字节输出流: ObjectOutputStream

构造器

说明

public ObjectOutputStream(OutputStream out)

把低级字节输出流包装成高级的对象字节输出流

ObjectOutputStream序列化方法

方法名称

说明

public final void writeObject(Object obj)

把对象写出去到对象序列化流的文件中去

import java.io.Serializable;

/**
  对象如果要序列化,必须实现Serializable序列化接口。
 */
public class Student implements Serializable {
    // 申明序列化的版本号码
    // 序列化的版本号与反序列化的版本号必须一致才不会出错!
    private static final long serialVersionUID = 1;
    private String name;
    private String loginName;
    // transient修饰的成员变量不参与序列化了
    private transient String passWord;
    private int age ;

    public Student(){
    }

    public Student(String name, String loginName, String passWord, int age) {
        this.name = name;
        this.loginName = loginName;
        this.passWord = passWord;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public String getLoginName() {
        return loginName;
    }

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

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", loginName='" + loginName + '\'' +
                ", passWord='" + passWord + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

/**
     目标:学会对象序列化,使用 ObjectOutputStream 把内存中的对象存入到磁盘文件中。

     transient修饰的成员变量不参与序列化了
     对象如果要序列化,必须实现Serializable序列化接口。

     申明序列化的版本号码
     序列化的版本号与反序列化的版本号必须一致才不会出错!
     private static final long serialVersionUID = 1;
 */
public class ObjectOutputStreamDemo1 {
    public static void main(String[] args) throws Exception {
        // 1、创建学生对象
        Student s = new Student("陈磊", "chenlei","1314520", 21);

        // 2、对象序列化:使用对象字节输出流包装字节输出流管道
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day20/src/obj.txt"));

        // 3、直接调用序列化方法
        oos.writeObject(s);

        // 4、释放资源
        oos.close();
        System.out.println("序列化完成了~~");

    }
}

对象反序列化

使用到的流是对象字节输入流: ObjectInputStream
作用:以内存为基准, 把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化

构造器

说明

public ObjectInputStream(InputStream out)

把低级字节输如流包装成高级的对象字节输入流

ObjectInputStream序列化方法

方法名称

说明

public Object readObject()

把存储到磁盘文件中去的对象数据恢复成内存中的对象返回

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

/**
    目标:学会进行对象反序列化:使用对象字节输入流把文件中的对象数据恢复成内存中的Java对象。
 */
public class ObjectInputStreamDemo2 {
    public static void main(String[] args) throws Exception {
        // 1、创建对象字节输入流管道包装低级的字节输入流管道
        ObjectInputStream is = new ObjectInputStream(new FileInputStream("day20/src/obj.txt"));

        // 2、调用对象字节输入流的反序列化方法
        Student s = (Student) is.readObject();

        System.out.println(s);
    }
}

4、打印流

打印流

作用:打印流可以实现方便、高效的打印数据到文件中去 。打印流一般是指: PrintStream PrintWriter 两个类。
可以实现打印什么数据就是什么数据,例如打印整数 97 写出去就是 97 ,打印 boolean true ,写出去就是 true

PrintStream

构造器

说明

public PrintStream(OutputStream os)

打印流直接通向字节输出流管道

public PrintStream(File  f)

打印流直接通向文件对象

public PrintStream(String filepath)

打印流直接通向文件路径

方法

说明

public void print(Xxx xx)

打印任意类型的数据出去

PrintWriter

构造器

说明

public PrintWriter(OutputStream os)

打印流直接通向字节输出流管道

public PrintWriter (Writer w)

打印流直接通向字符输出流管道

public PrintWriter (File  f)

打印流直接通向文件对象

public PrintWriter (String filepath)

打印流直接通向文件路径

方法

说明

public void print(Xxx xx)

打印任意类型的数据出去

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;

/**
    目标:学会使用打印流 高效  方便写数据到文件。
 */
public class PrintDemo1 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个打印流对象
//        PrintStream ps = new PrintStream(new FileOutputStream("io-app2/src/ps.txt"));
//        PrintStream ps = new PrintStream(new FileOutputStream("io-app2/src/ps.txt" , true)); // 追加数据,在低级管道后面加True
//        PrintStream ps = new PrintStream("io-app2/src/ps.txt" );
        PrintWriter ps = new PrintWriter("io-app2/src/ps.txt"); // 打印功能上与PrintStream的使用没有区别

        ps.println(97);
        ps.println('a');
        ps.println(23.3);
        ps.println(true);
        ps.println("我是打印流输出的,我是啥就打印啥");

        ps.close();
    }
}

PrintStreamPrintWriter的区别

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

输出语句重定向

属于打印流的一种应用,可以把输出语句的打印位置改到文件。
import java.io.FileOutputStream;
import java.io.PrintStream;

/**
    目标:了解改变输出语句的位置到文件
 */
public class PrintDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("锦瑟无端五十弦");
        System.out.println("一弦一柱思华年");

        // 改变输出语句的位置(重定向)
        PrintStream ps = new PrintStream("io-app2/src/log.txt");
        System.setOut(ps); // 把系统打印流改成我们自己的打印流

        System.out.println("庄生晓梦迷蝴蝶");
        System.out.println("望帝春心托杜鹃");
    }
}

5、Properties

Properties属性集对象

        其实就是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用。

Properties核心作用:

Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。

PropertiesAPI:

Properties和IO流结合的方法:

构造器

说明

void load​(InputStream inStream)

从输入字节流读取属性列表(键和元素对)

void load​(Reader reader)

从输入字符流读取属性列表(键和元素对)

void store​(OutputStream out, String comments)

将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流

void store​(Writer writer, String comments)

将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流

public Object setProperty(String key, String value)

保存键值对(put

public String getProperty(String key)

使用此属性列表中指定的键搜索属性值 (get)

public Set<String> stringPropertyNames()

所有键的名称的集合  (keySet())

import java.io.FileWriter;
import java.util.Properties;

/**
    目标:Properties的概述和使用(框架底层使用,了解这个技术即可)(保存数据到属性文件)

    Properties: 属性集对象。
         其实就是一个Map集合。也就是一个键值对集合,但是我们一般不会当集合使用,
         因为有HashMap。

    Properties核心作用:
         Properties代表的是一个属性文件,可以把键值对的数据存入到一个属性文件中去。
         属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value。

    大家在后期学的很多大型框架技术中,属性文件都是很重要的系统配置文件。
        users.properties
                admin=123456
                dlei=dlei

     需求:使用Properties对象生成一个属性文件,里面存入用户名和密码信息。

     Properties的方法:
         -- public Object setProperty(String key, String value) : 保存一对属性。  (put)
         -- public String getProperty(String key) : 使用此属性列表中指定的键搜索属性值 (get)
         -- public Set<String> stringPropertyNames() : 所有键的名称的集合  (keySet())
         -- public void store(OutputStream out, String comments): 保存数据到属性文件中去
         -- public void store(Writer fw, String comments): 保存数据到属性文件中去

     小结:
            Properties可以保存键值对数据到属性文件

 */
public class PropertiesDemo01 {
    public static void main(String[] args) throws Exception {
        // 需求:使用Properties把键值对信息存入到属性文件中去。
        Properties properties = new Properties();
        properties.setProperty("admin", "123456");
        properties.setProperty("dlei", "003197");
        properties.setProperty("heima", "itcast");
        System.out.println(properties);

        /**
           参数一:保存管道 字符输出流管道
           参数二:保存心得
         */
        properties.store(new FileWriter("io-app2/src/users.properties")
                , "this is users!! i am very happy! give me 100!");

    }
}
import java.io.FileReader;
import java.util.Properties;
import java.util.Set;

/**
    目标:Properties读取属性文件中的键值对信息。(读取)
    Properties的方法:
        -- public Object setProperty(String key, String value) : 保存一对属性。
        -- public String getProperty(String key) :使用此属性列表中指定的键搜索属性值
        -- public Set<String> stringPropertyNames() :所有键的名称的集合
        -- public void store(OutputStream out, String comments):保存数据到属性文件中去
        -- public synchronized void load(InputStream inStream):加载属性文件的数据到属性集对象中去
        -- public synchronized void load(Reader fr):加载属性文件的数据到属性集对象中去
    小结:
        属性集对象可以加载读取属性文件中的数据!!
 */
public class PropertiesDemo02 {
    public static void main(String[] args) throws Exception {
        // 需求:Properties读取属性文件中的键值对信息。(读取)
        Properties properties = new Properties();
        System.out.println(properties);

        // 加载属性文件中的键值对数据到属性对象properties中去
        properties.load(new FileReader("io-app2/src/users.properties"));

        System.out.println(properties);
        String rs = properties.getProperty("dlei");
        System.out.println(rs);
        String rs1 = properties.getProperty("admin");
        System.out.println(rs1);
    }
}

6、IO框架

commons-io概述

commons-io apache 开源基金组织提供的一组有关 IO 操作的类库,可以提高 IO 功能开发的效率。
commons-io 工具包提供了很多有关 io 操作的类。有两个主要的类 FileUtils , IOUtils

FileUtils主要有如下方法:

方法名

说明

String readFileToString(File file, String encoding)

读取文件中的数据, 返回字符串

void copyFile(File srcFile, File destFile)

复制文件。

void copyDirectoryToDirectory(File srcDir, File destDir)

复制文件夹。

导入commons-io-2.6.jar做开发

需求

使用 commons-io 简化 io 流读写

分析

在项目中创建一个文件夹: lib
commons-io-2.6.jar 文件复制到 lib 文件夹
jar 文件上点右键,选择 Add as Library -> 点击 OK
在类中导包使用
import org.apache.commons.io.FileUtils;
import java.io.File;

/**
    目标:Commons-io包的使用介绍。

    什么是Commons-io包?
            commons-io是apache开源基金组织提供的一组有关IO操作的类库,
            可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类,

    见下表:
         | 包                                  | 功能描述                                     |
         | ----------------------------------- | :------------------------------------------- |
         | org.apache.commons.io               | 有关Streams、Readers、Writers、Files的工具类 |
         | org.apache.commons.io.input         | 输入流相关的实现类,包含Reader和InputStream  |
         | org.apache.commons.io.output        | 输出流相关的实现类,包含Writer和OutputStream |
         | org.apache.commons.io.serialization | 序列化相关的类

    步骤:
         1. 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/
         2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中
         3. 将commons-io-2.6.jar加入到classpath中

    小结:
         IOUtils和FileUtils可以方便的复制文件和文件夹!!
 */
public class CommonsIODemo01 {
    public static void main(String[] args) throws Exception {

        // 1.完成文件复制!
//        IOUtils.copy(new FileInputStream("D:\\resources\\hushui.jpeg"),
//                new FileOutputStream("D:\\resources\\hushui2.jpeg"));


        // 2.完成文件复制到某个文件夹下!
//        FileUtils.copyFileToDirectory(new File("D:\\resources\\hushui.jpeg"), new File("D:/"));


          // 3.完成文件夹复制到某个文件夹下!
//          FileUtils.copyDirectoryToDirectory(new File("D:\\resources") , new File("D:\\new"));
//           FileUtils.deleteDirectory(new File("D:\\new"));

         // JDK1.7 自己也做了一些一行代码完成复制的操作:New IO的技术
         // Files.copy(Path.of("D:\\resources\\hushui.jpeg"), Path.of("D:\\resources\\hushui3.jpeg"));

        FileUtils.deleteDirectory(new File("D:\\new"));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值