25、IO流(字符串编解码、字符流、OutputStreamWriter、InputStreamReader、FileWriter、FileReader、BufferedWriter、BufferReader、练习)

字符流

字符流出现的原因:由于字节流操作中文不是特别方便,常常需要根据编码方式选择每次读取的字节数,所以,java就提供了字符流。

字符流:字节流 + 编码方式。

字符流只能操作文本文件。

String的编解码

方法名 描述
public byte[] getBytes() 使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中
public byte[] getBytes(String charsetName) 使用指定名称的字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中
public String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
public String(byte[] bytes, String charsetName) 通过使用指定的字符集解码指定的byte数组,构造一个新的String

使用平台默认的字符集编解码

package org.westos.demo;


import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/25 18:47
 */
public class MyTest {
    public static void main(String[] args) {
        /*
        编码:把字符串按照编码方式转换为字节数组,把看得懂的变为看不懂的
        解码:把字节数组按照编码方式转换为字符串,把看不懂的变为看的懂的
         */

        String s = new String("黑龙江");
        byte[] bytes = s.getBytes();
        //使用默认编码方式编码
        System.out.println(Arrays.toString(bytes));
        //[-23, -69, -111, -23, -66, -103, -26, -79, -97]

        String s1 = new String(bytes);
        //使用默认编码方式解码
        System.out.println(s1);
        //黑龙江
    }
}

使用GBK编码字符串,再使用"UTF-8"解码

package org.westos.demo;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/25 18:51
 */
public class MyTest2 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = new String("中文乱码问题");
        byte[] bytes = s.getBytes("GBK");
        //使用GBK编码方式编码
        System.out.println(Arrays.toString(bytes));
        //[-42, -48, -50, -60, -62, -46, -62, -21, -50, -54, -52, -30]

        String s1 = new String(bytes, StandardCharsets.UTF_8);
        //使用UFT-8编码方式解码
        //public String(byte[] bytes, Charset charset)
        System.out.println(s1);
        //������������
        //编码解码方式不同,产生中文乱码问题
    }
}

使用GBK编解码

package org.westos.demo;

import java.io.UnsupportedEncodingException;

/**
 * @author lwj
 * @date 2020/5/26 8:50
 */
public class MyTest3 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = new String("GBK编码的字符串");
        byte[] bytes = s.getBytes("GBK");
        //使用GBK编码字符串

        String s1 = new String(bytes, "GBK");
        //使用GBK进行解码字符串
        System.out.println(s1);
        //GBK编码的字符串
    }
}

用什么编码,就用什么解码。

OutputStreamWriter

public class OutputStreamWriter extends Writer { }

构造方法

OutputStreamWriter(OutputStream out) 
//使用默认编码输出数据
OutputStreamWriter(OutputStream out, String charsetName) 
OutputStreamWriter(OutputStream out, Charset cs) 
//使用指定编码输出数据

字符流,就是在字节流的基础上,设置字符集参数。

参数是OutputStream字节输出流类型,所以需要传递一个字节输出流的实现类对象(比如FileOutputStream文件输出流对象)和一个编码方式(默认为utf-8)。

使用平台默认字符集

package org.westos.demo2;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @author lwj
 * @date 2020/5/25 19:01
 */
public class MyTest {
    public static void main(String[] args) {
        //输出流所关联的文件如果不存在,会自动创建
        //字符流包装了字节流
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(new FileOutputStream(
                    new File("src\\org\\westos\\demo2\\a.txt"), true), StandardCharsets.UTF_8);
            //FileOutputStream字节输出流的构造方法,一个File,一个append是否允许追加
            //OutputStreamWriter字符输出流的构造方法,一个FileOutputStream,一个编码方式(把字符串按照某种编码方式转换为字节数组)
            osw.write('我');
            //write(int c) 写入一个字符
            osw.write("\r\n");
            osw.write("爱奇艺会员");
            //write(String s) 写入一个字符串
            osw.write("\r\n你有吗?".toCharArray());
            //write(char[] ch) 写入一个字符数组
            osw.write("\r\n");
            osw.write("麻烦借我一下好吗", 2, 4);
            //write(String s, int off, int len) 写入字符串的一部分
            osw.write("\r\n");
            osw.write("谢谢".toCharArray(), 0, 2);
            //write(char[] ch, int off, int len) 写入字符数组的一部分

            osw.flush();
            //输出流记得flush
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (osw != null) {
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

a.txt文件

我
爱奇艺会员
你有吗?
麻烦借我一下
谢谢

使用GBK字符集

package org.westos.demo2;

import java.io.*;

/**
 * @author lwj
 * @date 2020/5/25 19:40
 */
public class MyTest2 {
    public static void main(String[] args) {
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(new FileOutputStream(
                    new File("src\\org\\westos\\demo2\\b.txt"), true), "GBK");
            //使用GBK编码方式的字符流
            osw.write("我是GBK类型的文件");
            osw.write("\r\n");
            osw.write("文件类型必须转为GBK才可以查看文件".toCharArray());
            
            osw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (osw != null) {
                    osw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

InputStreamReader

public class InputStreamReader extends Reader { }

构造方法

InputStreamReader(InputStream in)
//使用默认编码读取数据
InputStreamReader(InputStream in, String charsetName) 
InputStreamReader(InputStream in, Charset cs)
//使用指定编码读取数据

输入字符流。

使用平台默认字符集

c.txt

acbdefgABCDEFG爱上对方过后就卡了
package org.westos.demo3;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/25 20:08
 */
public class MyTest {
    public static void main(String[] args) {
        InputStreamReader isr = null;
        try {
            isr = new InputStreamReader(new FileInputStream(new File(
                    "src\\org\\westos\\demo3\\c.txt")), StandardCharsets.UTF_8);
            //字符输入流InputStreamReader
            //字节输入流的文件如果不存在会报错
            int read = isr.read();
            //read() 读取一个字符
            System.out.println((char) read);
            char[] chars = new char[5];
            int len = 0;
            while ((len = isr.read(chars)) != -1) {
                //read(char[] chars) 读取一个字符数组
                System.out.println(new String(chars, 0, len));
                //new String(char[], int offset, int len)
            }
            /*
            a
            cbdef
            gABCD
            EFG爱上
            对方过后就
            卡了
             */
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用GBK字符集

d.txt

我是GBK类型的文件,必须用GBK解码的字符流才可以读取。
package org.westos.demo3;

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

/**
 * @author lwj
 * @date 2020/5/26 15:22
 */
public class MyTest2 {
    public static void main(String[] args) {
        InputStreamReader isr = null;
        try {
            isr = new InputStreamReader(new FileInputStream(new File(
                    "src\\org\\westos\\demo3\\d.txt")), "GBK");
            //读取b.txt文件,GBK解码
            char[] chars = new char[5];
            int len = 0;
            while ((len = isr.read(chars)) != -1) {
                System.out.println(new String(chars, 0, len));
            }
            /*
            我是GBK
            类型的文件
            ,必须用G
            BK解码的
            字符流才可
            以读取。
             */
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字符流复制文本文件

复制平台默认编码的文件

我们复制一个Java文件。

package org.westos.demo4;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 字符流复制文本文件
 * @author lwj
 * @date 2020/5/26 15:42
 */
public class MyDemo {
    public static void main(String[] args) {
        InputStreamReader isr = null;
        OutputStreamWriter osw = null;
        try {
            isr = new InputStreamReader(new FileInputStream(
                    new File("src\\org\\westos\\demo\\MyTest.java")), StandardCharsets.UTF_8);
            //使用平台默认的编码方式解码
            osw = new OutputStreamWriter(new FileOutputStream(
                    new File("src\\org\\westos\\demo4\\MyTest.java"), true), StandardCharsets.UTF_8);
            //使用平台默认的编码方式编码
            char[] chars = new char[10];
            int index = 0;
            int len = 0;
            while ((len = isr.read(chars)) != -1) {
                index++;
                osw.write(chars, 0, len);
                osw.flush();
            }
            System.out.println(index);
            //63
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (osw != null) {
                        osw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

复制GBK编码的文件

package org.westos.demo4;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @author lwj
 * @date 2020/5/26 17:47
 */
public class MyDemo2 {
    public static void main(String[] args) {
        InputStreamReader isr = null;
        OutputStreamWriter osw = null;
        try {
            isr = new InputStreamReader(new FileInputStream(
                    new File("src\\org\\westos\\demo2\\b.txt")), "GBK");
            //用GBK解码
            osw = new OutputStreamWriter(new FileOutputStream(
                    new File("src\\org\\westos\\demo4\\e.txt")), StandardCharsets.UTF_8);
            //用UTF-8编码
            char[] chars = new char[20];
            int len = 0;
            while ((len = isr.read(chars)) != -1) {
                osw.write(chars, 0, len);
                osw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (osw != null) {
                        osw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileWriter和FileReader

字符流OutputStreamWriter和InputStreamReader的名称太长,所以提供了一个他们的子类。(字符流便捷类)

public class FileReader extends InputStreamReader {}
public class FileWriter extends OutputStreamWriter {}

构造方法

FileReader(File file) 
//按照默认的编码方式解码
FileWriter(File file) 
//按照默认的编码方式编码
FileWriter(File file, boolean append) 
//按照默认的编码方式编码,并且允许文件追加

便捷字符流类:

缺点:只能使用平台默认编码;

使用便捷字符流类复制文件

package org.westos.demo5;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * FileReader和FileWriter
 * @author lwj
 * @date 2020/5/26 17:40
 */
public class MyTest {
    public static void main(String[] args) {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader(new File("src\\org\\westos\\demo2\\a.txt"));
            //使用平台默认编码进行解码
            fw = new FileWriter(new File("src\\org\\westos\\demo5\\f.txt"), true);
            char[] chars = new char[10];
            int len = 0;
            while ((len = fr.read(chars)) != -1) {
                fw.write(chars, 0, len);
                fw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fw != null) {
                        fw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

BufferedWriter和BufferedReader

缓冲字符流

public class BufferedWriter extends Writer {}
public class BufferedReader extends Reader {}

构造方法

BufferedWriter(Writer out)
BufferedReader(Reader in) 

使用缓冲字符流类复制文件

package org.westos.demo5;

import java.io.*;

/**
 * 字符缓冲流
 * @author lwj
 * @date 2020/5/26 18:26
 */
public class MyTest2 {
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(new File("src\\org\\westos\\demo2\\a.txt")));
            //new FileReader / new InputStreamReader
            bw = new BufferedWriter(new FileWriter(new File("src\\org\\westos\\demo5\\g.txt"), true));
            //new FileWriter / new OutputStreamWriter
            String s = null;
            while ((s = br.readLine()) != null) {
                //BufferReader的readLine()方法读取一行数据,如果读取不到返回null
                bw.write(s);
                //写入字符串
                bw.newLine();
                //写入一个行分隔符,具有平台兼容性
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bw != null) {
                        bw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

练习

把集合中的数据存储到文本文件

package org.westos.test;

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

/**
 * @author lwj
 * @date 2020/5/26 19:58
 */
public class MyTest {
    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>();
        strings.add("第一个出场");
        strings.add("不是因为lady优先");
        strings.add("是因为我带着冠军制作人的头衔");
        strings.add("没人能阻挡  全部待在我的后面");
        strings.add("台上有我   其他人根本无法露面");
        strings.add("I am the champion");
        strings.add("举手投足");
        strings.add("Shine bright like a gem");
        strings.add("比任何人都出彩");
        strings.add("摘下过去头顶那些光环");
        strings.add("来日的胜利却会更壮观");
        strings.add("即使夜再漆黑 我再疲惫");
        strings.add("对我打击微乎其微  累不气馁");
        strings.add("无愧美誉地位   我踏实地每步积累");
        strings.add("自古以来真正厉害的偶像");
        strings.add("无反顾带领新一代的走向");
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(new File("src\\org\\westos\\test\\gem.txt"), true));
            //BufferedWriter的构造方法参数是一个Writer
            for (String string : strings) {
                writer.write(string);
                writer.newLine();
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

把文本文件中的数据存储到集合中

package org.westos.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/26 20:21
 */
public class MyTest2 {
    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(new File("src\\org\\westos\\test\\gem.txt")));
            //BufferedReader(Reader)
            //FileReader使用平台默认字符集解码
            String s = null;
            while ((s = reader.readLine()) != null) {
                strings.add(s);
            }
            for (String string : strings) {
                System.out.println(string);
            }
            /*
            第一个出场
            不是因为lady优先
            是因为我带着冠军制作人的头衔
            没人能阻挡  全部待在我的后面
            台上有我   其他人根本无法露面
            I am the champion
            举手投足
            Shine bright like a gem
            比任何人都出彩
            摘下过去头顶那些光环
            来日的胜利却会更壮观
            即使夜再漆黑 我再疲惫
            对我打击微乎其微  累不气馁
            无愧美誉地位   我踏实地每步积累
            自古以来真正厉害的偶像
            无反顾带领新一代的走向
             */
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

复制指定目录下指定后缀名的文件并改名

package org.westos.test;

import java.io.*;

/**
 * @author lwj
 * @date 2020/5/26 20:36
 */
public class MyDemo {
    public static void main(String[] args) {
        File source = new File("src\\org\\westos\\test2");
        File dest = new File("src\\org\\westos\\test3");
        if (!dest.exists()) {
            dest.mkdir();
        }
        File[] sourceFiles = source.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isFile() && name.endsWith(".java");
            }
        });
        for (File sourceFile : sourceFiles) {
            String name = sourceFile.getName();
            name = name.replace(".java", ".jad");
            copyFile(sourceFile, new File(dest, name));
        }
    }

    public static void copyFile(File source, File dest) {
        BufferedWriter writer = null;
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(source));
            writer = new BufferedWriter(new FileWriter(dest, true));
            String s = null;
            while ((s = reader.readLine()) != null) {
                writer.write(s);
                writer.newLine();
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

键盘录入学生信息按照总分排序并写入文本文件

package org.westos.test;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @author lwj
 * @date 2020/5/26 20:54
 */
public class MyDemo2 {
    public static void main(String[] args) throws IOException {
        ArrayList<Student> students = new ArrayList<>();
        Scanner sc = new Scanner(System.in);
        int index = 0;
        while (index < 3) {
            System.out.println("请输入学生姓名,语文成绩,数学成绩和英语成绩,之间用空格分隔:(张三 80 80 80)");
            String name = sc.next();
            int chineseScore = sc.nextInt();
            int mathScore = sc.nextInt();
            int englishScore = sc.nextInt();
            students.add(new Student(name, chineseScore, mathScore, englishScore));
            index++;
        }
        //使用Collections.sort(list, Comparator)或者ArrayList的sort方法
        students.sort(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return -Integer.compare(o1.getTotalScore(), o2.getTotalScore());
                //按照总分从高到低
            }
        });
        BufferedWriter writer = new BufferedWriter(new FileWriter(
                new File("src\\org\\westos\\test\\student.txt"), true));
        for (Student student : students) {
            writer.write(student.toString());
            writer.newLine();
            writer.flush();
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/shawnyue-08/p/12968753.html