Java开发从入门到精通(二十):Java的面向对象编程OOP:IO流文件操作的读取和写入

(一)Java的IO流文件读写

1.1 IO流前置知识

  • 字符集、UTF-8、GBK、ASCII、乱码问题、编码和解码等

1.1.1 ASCII字符集

美国人发明了计算机以后就把自己的字符录入到系统中,也就是英文、数字、标点、特殊符号,但是计算机只能识别0、1,所以为了能使用这些字符,美国人发明了ASCII 将所用到字符编写为特定的编号,从0-127 ,这些被称为码点 也叫ASCII,然后把ASCII通过编码的方式写进计算机,也就是将编号0-127转换成二进制数表示,但是这些字符的二进制不够八位,不够的补0,使用了一个字节来存储。
在这里插入图片描述

  • 标准ASCII字符集 ASCll(American standard Code for Information Interchange):美国信息交换标准代码,包括了英文、符号等
  • 标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符

1.1.2 GBK字符集

随着计算机的普及,计算机进入中国,中国人将自己的字符编写成GBK汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储。这就是人们常说的GBK编码 专业名称是(汉字内码扩展规范,国标)
注意:GBK兼容了ASCII字符集。

为了区分ASCII和GBK编码 规定ASCII首字节是0 GBK首字节是1

在这里插入图片描述
在这里插入图片描述

1.1.3 Unicode字符集

随着越来越多的国家使用计算机,编码方式也越来越多,为了能够统一全世界的编码格式,国际组织制定了Unicode字符集,可以容纳世界上所有文字、符号的字符集。其中有很多编码方法比如UTF-32 ,使用4个字节表示一个字符,不被使用的原因是比较奢侈!占存储空间,通信效率变低

1.1.4 UTF-8字符集

  • 由于UTF-32 的设计不符合大家的要求,国际组织制定重新制定了UTF-8,是Unicode字符集的另一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节
  • 英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节
    在这里插入图片描述

UTF-8编码规则:

  • 字符如果是一个字节 应该以0开头
  • 字符如果是两个字节 应该以110 10 开头
  • 字符如果是三个字节 应该以110 10 10 开头
  • 字符如果是四个个字节 应该以110 10 10 10开头

注意:技术人员在开发时都应该使用UTF-8编码!

要点记忆部分

  • ASCII字符集:只有英文、数字、符号等,占1个字节
  • GBK字符集:汉字占2个字节,英文、数字占1个字节
  • UTF-8字符集:汉字占3个字节,英文、数字占1个字节

注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
注意2:英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码

在这里插入图片描述

1.1.4 Java的编码解码

  • 编码:把字符按照指定字符集编码成字节。

在这里插入图片描述

  • 解码:把字节按照指定字符集解码成字符。

在这里插入图片描述

import java.util.Arrays;

public class ZiFu {
    public static void main(String[] args) throws Exception {
        // 1、编码
        String data ="a我b";
        byte[] bytes = data.getBytes(); // 默认是按照平台字符集(UTF-8)进行编码的。
        System.out.println(Arrays.toString(bytes));

        // 按照指定字符集进行编码。
        byte[] bytes1 = data.getBytes(  "GBK");
        System.out.println(Arrays.toString(bytes1));
        
        
        // 2、解码
        String s1= new String(bytes);// 按照平台默认编码(UTF-8)解码
        System.out.println(s1);
        
		// 按照指定字符集进行解码。
        String s2 =new String(bytes1,"GBK");
        System.out.println(s2);
    }
}

1.2 IO流的基础知识

1.2.1 认识I0流

IO流概述

  • I指Input,称为输入流:负责把数据读到内存中去
  • 0指Output,称为输出流:负责写数据出去
    在这里插入图片描述

1.2.2 应用场景

在这里插入图片描述

1.2.3 如何学I0流

1.2.3.1 先搞清楚I0流的分类、体系:
  • I0流的分类

在这里插入图片描述
在这里插入图片描述

总结流的四大类:

  • 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
  • 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流。
  • 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。
  • 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。

Java.io包下

  • I0流的体系
    在这里插入图片描述
    在这里插入图片描述
1.2.3.1 再挨个学习每个I0流的作用、用法。
1.2.3.1 字节流的用法
1.2.3.1.1 FilelnputStream文件字节输入流:每次读取一个字节

FilelnputStream(文件字节输入流)
作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去
在这里插入图片描述
在这里插入图片描述

import java.io.FileInputStream;
import java.io.InputStream;

public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、创建文件字节输入流管道,与源文件接通。
        InputStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"))
        // 简化写法:推荐使用。
        InputStream is = new FileInputStream(("file-io-app\\src\\itheima1.txt"));

        //2、开始读取文件的字节数据。
        // public int read():每次读取一个字节返回,如果没有数据了,返回-1.
        int b1 = is.read();
        System.out.println((char)b1);

        int b2 = is.read();
        System.out.println((char)b2);

        int b3 = is.read();
        System.out.println(b3);

        // 3、使用循环改造上述代码
        int b;
        // 用于记住读取的字节。
        while((b=is.read())!= -1) {
            System.out.print((char) b);
        }
        // 读取数据的性能很差!
        // 读取汉字输出会乱码!!无法避免的!!
        // 流使用完毕之后,必须关闭!释放系统资源!2
        is.close();
    }
}
1.2.3.1.2 FilelnputStream文件字节输入流:每次读取多个字节
import java.io.FileInputStream;
import java.io.InputStream;

public class FileInputTest {
    public static void main(String[] args) throws Exception {
        InputStream is =new FileInputStream("/1.txt");

        // 2、开始读取文件中的字节数据:每次读取多个字节。
        // public int read(byte b[])throws IOException
        // 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.
        byte[] buffer = new byte[3];
        int len = is.read(buffer);
        String rs=new String(buffer);
        System.out.println(rs);
        System.out.println("当次读取的字节数量:"+ len);
        // buffer = [abc]
        // buffer = [66c]
        int len2 = is.read(buffer);
        // 注意:读取多少,倒出多少。
        String rs2 = new String(buffer,0,len2);
        System.out.println(rs2);
        System.out.println("当次读取的字节数量:"+ len2);
        
        int len3 = is.read(buffer);
        System.out.println(len3);//-1
    }
}

优化代码

public class FileInputTest {
    public static void main(String[] args) throws Exception {
        InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");
        
        // 2、开始读取文件中的字节数据:每次读取多个字节。
        // public int read(byte b[])throws IOException
        // 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.
        // 3、使用循环改造。
        byte[] buffer = new byte[3];
        int len;// 记住每次读取了多少个字节。abc 66
        while((len=is.read(buffer))!=-1) {
            // 注意:读取多少,倒出多少。
            String rs = new String(buffer, 0, len);
            System.out.print(rs);
        }
        is.close();// 关闭流
        // 性能得到了明显的提升!!
        // 这种方案也不能避免读取汉字输出乱码的问题!!
    }
}
  • 使用FilelnputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码
1.2.3.1.3 FilelnputStream文件字节输入流:一次读取完全部字节

方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
在这里插入图片描述

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
        InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");

        // 2、准备一个字节数组,大小与文件的大小正好一样大。
        File f = new File("lianxi\\src\\com\\qianxin\\file\\1.txt");
        long size = f.length();
        byte[] buffer =new byte[(int) size];

        int len = is.read(buffer);
        System.out.println(new String(buffer));

        System.out.println(size);
        System.out.println(len);
    }
}

lianxi\src\com\qianxin\file\1.txt 内容

public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
1163
1163

方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。
在这里插入图片描述

import java.io.FileInputStream;
import java.io.InputStream;


public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
        InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");
        byte[] buffer = is.readAllBytes();
        System.out.println(new String(buffer));
        is.close();
    }
}

1、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?

  • 如果文件过大,创建的字节数组也会过大,可能引起内存溢出,
  • 字符流:读写文本内容更适合用
  • 字节流:适合做数据的转移,如:文件复制等
1.2.3.1.4 FileOutputstream文件字节输出流:写字节出去

FileOutputstream(文件字节输出流)
作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

import java.io.FileOutputStream;
import java.io.OutputStream;

public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
        OutputStream os = new FileOutputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");

        // 2、开始写字节数据出去了
        os.write(97); //97就是一个字节,代表a
        os.write('b'); //'b'也是一个字节
        os.write('磊');// [ooo]默认只能写出去一个字节

        byte[] bytes ="我爱你中国abc".getBytes();
        os.write(bytes);
        os.write(bytes,0,15);
        os.close();//关闭流
    }
}

写入文件不覆盖之前的内容 FileOutputStream(“lianxi\src\com\qianxin\file\1.txt”,true);

import java.io.FileOutputStream;
import java.io.OutputStream;


public class FileInputTest {
    public static void main(String[] args) throws Exception {
        // 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
        OutputStream os = new FileOutputStream("lianxi\\src\\com\\qianxin\\file\\1.txt",true);

        // 2、开始写字节数据出去了
        os.write(97); //97就是一个字节,代表a
        os.write('b'); //'b'也是一个字节
        os.write('磊');// [ooo]默认只能写出去一个字节

        byte[] bytes ="我爱你中国abc".getBytes();
        os.write(bytes);
        os.write(bytes,0,15);

        // 换行符
        os.write("\r\n".getBytes());

        os.close();//关闭流
    }
}
1.2.3.1.5 案例:文件复制

在这里插入图片描述

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;

public class FileCopyTest {
    public static void main(String[] args) throws Exception {
        // 需求:复制照片。
        // 1、创建一个字节输入流管道与源文件接通
        InputStream is = new FileInputStream( "D:/resource/meinv.png");
        // 2、创建一个字节输出流管道与目标文件接通。
        OutputStream os = new FileOutputStream("c:/data/meinv.png");
        //1024+1024 +6
        // 3、创建一个字节数组,负责转移字节数据。
        byte[] buffer =new byte[1024];//1KB
        // 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
        int len;// 记住每次读取了多少个字节。
        while((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
        }
        os.close();
        is.close();
        System.out.println("复制完成!!");
    }
}

字节流非常适合做一切文件的复制操作

  • 任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,只要复制后的文件格式一致就没问题!
1.2.3.2 释放资源的方式

如果文件操作中间的代码出现异常,那么最后的释放文件读写资源的close将不会被执行,导致长时间占用资源,所以需要使用一些释放资源的方法,保证即使前面的代码有问题也能将资源释放,提高性能

1.2.3.2.1 try-catch-finally

finaly代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非IVM终止。

  • 作用:一般用于在程序执行完成后进行资源的释放操作(专业级做法)

在这里插入图片描述

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args){
        InputStream is= null;
        OutputStream os = null;
        try {
            // 需求:复制照片。
            // 1、创建一个字节输入流管道与源文件接通
            is = new FileInputStream("D:/resource/meinv.png");
            // 2、创建一个字节输出流管道与目标文件接通。
            os = new FileOutputStream("c:/data/meinv.png");
            //1024+1024 +6
            // 3、创建一个字节数组,负责转移字节数据。
            byte[] buffer = new byte[1024];//1KB
            // 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
            int len;// 记住每次读取了多少个字节。
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }

            System.out.println("复制完成!!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源的操作
            try {
                if (is != null) os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
1.2.3.2.2 try-with-resource

JDK 7开始提供了更简单的资源释放方案:try-with-resource,try-catch-finally提供的资源释放代码过于臃肿

  • 完成对资源的释放!该资源使用完毕后,会自动调用其close()方法

在这里插入图片描述

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        // 需求:复制照片
        try (
                // 1、创建一个字节输入流管道与源文件接通
                InputStream is = new FileInputStream("D:\\resource\\ab.txt");
                // 2、创建一个字节输出流管道与目标文件接通。
                OutputStream os = new FileOutputStream("F:\\1");
        ) {
            // 1024 + 1024 + 6
            // 3、创建一个字节数组,负责转移字节数据。
            byte[] buffer = new byte[1024];//1KB
            // 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
            // 记住每次读取了多少个字节。
            int len;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成!!");

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

    }
}

try ()中只能放置资源,否则报错
什么是资源呢?
资源一般指的是最终实现了AutoCloseable接口,InputStream OutputStream 都继承了自动关闭的接口方法
在这里插入图片描述

1.2.3.3 字符流的用法

字节流:适合复制文件等,不适合读写文本文件
字符流:适合读写文本文件
在这里插入图片描述

1.2.3.3.1 FileReader文件字符输入流-读字符数据进来

FileReader(文件字符输入流)
作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。
在这里插入图片描述
在这里插入图片描述
每次读取一个字符

public class FileCopyTest {
    public static void main(String[] args) {
        try (
                //1 1、创建一个文件字符输入流管道与源文件接通
                Reader fr = new FileReader("io-app2\\src\\itheima01.txt");
        ) {
            // 2、读取文本文件的内容了。
            int c;// 记住每次读取的字符编号。
            while ((c = fr.read()) != -1) {
                System.out.print((char) c);
            }
            // 每次读取一个字符的形式,性能肯定是比较差的。

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

每次读取多个字符

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        try (
                //1 1、创建一个文件字符输入流管道与源文件接通
                Reader fr = new FileReader("io-app2\\src\\itheima01.txt");
        ) {
            // 3、每次读取多个字符。
            char[] buffer = new char[3];
            int len;// 记住每次读取了多少个字符。
            while ((len = fr.read(buffer)) != -1) {
                // 读取多少倒出多少
                System.out.print(new String(buffer, 0, len));
                // 性能是比较不错的!
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
1.2.3.3.2 FileWriter文件字符输出流-写字符数据出去

FileWriter(文件字符输出流)
作用:以内存为基准,把内存中的数据以字符的形式写出到文件中去。

字符输出流使用时的注意事项:
必须刷新流,或者关闭流,写出去的数据才能生效字符输出流写出数据后
在这里插入图片描述
在这里插入图片描述

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        try(
                //覆盖管道
                Writer fw = new FileWriter("D:\\resource\\ab.txt");
                //追加管道
                Writer fw = new FileWriter("D:\\resource\\ab.txt",true);
        ){
            // 1、public void write(int c):写一个字符出去
            fw.write("a");
            fw.write( 97);
            fw.write('磊');// 写一个字符出去
            fw.write("\r\n");

            // 2、public void write(String c)写一个字符串出去
            fw.write("我爱你中国abc");
            fw.write("\r\n");

            // 3、public void write(string c ,int pos ,int len):写字符串的一部分出去
            fw.write( "我爱你中国abc" ,0,5);
            fw.write("\r\n");

            // 4、public void write(char[] buffer):写一个字符数组出去
            char[] buffer ={'黑','马','a','b','c'};
            fw.write(buffer);
            fw.write("\r\n");

            // 5、public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
            fw.write(buffer,0,2);
            fw.write("\r\n");

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

flush刷新流close关闭流

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) throws IOException {

        Writer fw = new FileWriter("D:\\resource\\ab.txt", true);

        // 1、public void write(int c):写一个字符出去
        fw.write("a");
        fw.write(97);
        fw.write('磊');// 写一个字符出去
        fw.write("\r\n");

        fw.flush();// 刷新流。
        fw.write("张三");
        fw.flush();

        fw.close();// 刷新流,关闭流包含刷新作!
        
    }
}
1.2.3.3 缓冲流的用法
  • 对原始流进行包装,以提高原始流读写数据的性能

在这里插入图片描述

  • 原始流/低级流

在这里插入图片描述

  • 包装流/处理流

在这里插入图片描述

1.2.3.3.1 字节缓冲流的用法
  • 以文件复制为例

在这里插入图片描述

使用缓冲流32次变成了4次,提高了效率
在这里插入图片描述

  • 原理:字节缓冲输入流自带了8KB缓冲池;字节缓冲输出流也自带了8KB缓冲池

在这里插入图片描述

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) throws Exception {
        try (
            // 需求:复制照片。
            // 1、创建一个字节输入流管道与源文件接通
            InputStream is = new FileInputStream( "D:/resource/meinv.png");
            // 创建一个字节缓冲输入流包装原始的字节输入流
            InputStream bis =new BufferedInputStream(is);
            // 2、创建一个字节输出流管道与目标文件接通。
            OutputStream os = new FileOutputStream("c:/data/meinv.png");
            // 创建一个字节缓冲输出流包装原始的字节输出流
            OutputStream bos =new BufferedOutputStream(os);
            ){

            // 3、创建一个字节数组,负责转移字节数据。
            byte[] buffer =new byte[1024];//1KB
            // 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
            int len;// 记住每次读取了多少个字节。
            while((len=bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
            System.out.println("复制完成!!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
1.2.3.3.2 字符缓冲流的用法
  • 对原始流进行包装,以提高原始流读写数据的性能

BufferedReader(字符缓冲输入流)

  • 作用:自带8K(8192)的字符缓冲池,可以提高字符输入流读取字符数据的性能

在这里插入图片描述

  • 字符缓冲输入流新增的功能:按照行读取字符

在这里插入图片描述

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        try (
                //1 1、创建一个文件字符输入流管道与源文件接通
                Reader fr = new FileReader("D:\\\\resource\\\\ab.txt");
                // 创建一个字符缓冲输入流包装原始的字符输入流
                BufferedReader br = new BufferedReader(fr);
        ) {
            // 3、每次读取多个字符。
            char[] buffer = new char[3];
            int len;// 记住每次读取了多少个字符。
            while ((len = br.read(buffer)) != -1) {
                // 读取多少倒出多少
                System.out.print(new String(buffer, 0, len));
                // 性能是比较不错的!
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

readLine读取一行数据

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        try (
                // 1、创建一个文件字符输入流管道与源文件接通
                Reader fr = new FileReader("D:\\\\resource\\\\ab.txt");
                // 创建一个字符缓冲输入流包装原始的字符输入流
                BufferedReader br = new BufferedReader(fr);
        ) {

            String line;// 记住每次读取的一行数据
            while((line =br.readLine())!= null){
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

BufferedWriter(字符缓冲输出流)

  • 作用:自带8K的字符缓冲池,可以提高字符输出流写字符数据的性能
    在这里插入图片描述
    在这里插入图片描述

  • 字符缓冲输出流新增的功能:换行

在这里插入图片描述

package com.qianxin.file;

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        try(
                //追加管道
                Writer fw = new FileWriter("D:\\resource\\ab.txt",true);
                // 创建一个字符缓冲输出流管道包装原始的字符输出流
                BufferedWriter bw = new BufferedWriter(fw)
        ){
            // 1、public void write(int c):写一个字符出去
            bw.write("a");
            bw.write( 97);
            bw.write('磊');// 写一个字符出去
            bw.newLine();

            // 2、public void write(String c)写一个字符串出去
            bw.write("我爱你中国abc");
            bw.newLine();;

        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
1.2.3.3.3 缓冲流使用案例
  • 拷贝出师表到另一个文件,并恢复顺序

     3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
     8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先
     4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
     2.宫中府中、但为一体,陇罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
     1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣!
     9.今当远离,临表涕零,不知所言。
     6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,狠自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆
     7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶。
     5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞
    
package com.qianxin.file;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class FileCopyTest {
    public static void main(String[] args) {
        // 目标:恢复出师表的顺序到新文件中。
        try(
                // 2、创建缓冲字符输入输出流管道与源文件接通
                BufferedReader br = new BufferedReader(new FileReader("lianxi\\src\\com\\qianxin\\file\\1.txt"));
                BufferedWriter  bw = new BufferedWriter(new FileWriter("lianxi\\src\\com\\qianxin\\file\\2.txt"));

        ){
        
            //1、定义一个ArrayList集合存储每段内容
            List<String> list = new ArrayList<>();
            
            //3、按照行读取每段,存入到集合中去
            String line;
            while ((line = br.readLine()) != null){
                list.add(line);
            }
            
            //4、对List集合中的每段文章进行排序
            Collections.sort(list);
            
            // 5、遍历List集合的每段内容,依次写出去到新文件中。
            for (String ln : list) {
                bw.write(ln);
                bw.newLine();//换行
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
  • 回复顺序并写入新的文件

     1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣!
     2.宫中府中、但为一体,陇罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
     3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
     4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
     5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞
     6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,狠自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆
     7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶。
     8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先
     9.今当远离,临表涕零,不知所言。
    
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HACKNOE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值