Java总结IO篇之字符流

作者: e4e52c116681 | 来源:发表于2018-10-09 22:22 被阅读298次

    零、前言

    1.字符流只能操作文本
    2.本质底层依然是使用字节操作,只不过坐了一层封装
    3.字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,对多国语言支持性比较好

    一、字符流之FileWriter和FileReader

    1.字符流之FileWriter的使用

    注:new FileWriter(fileName,true) 追加模式添加数据

    FileWriter fileWriter = null;
    try {
        String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileWriter.txt";
        //1.创建一个输出流--写出文件:需明确被操作文件----文件不存在,会自动创建文件(同名覆盖)
        fileWriter = new FileWriter(fileName);
        //2.写入数据
        fileWriter.write("Line1 第一行\r\n");
        //3.刷新流中的缓冲
        fileWriter.flush();
        fileWriter.write("Line2 第二行");
        //获取文件编码格式
    System.out.println(fileWriter.getEncoding());//UTF8
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4.关闭流也会刷新缓冲
        try {
            //不为空,才能关闭流
            if (fileWriter != null) {
                fileWriter.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    FileWriter.png
    2.字符流之FileReader的使用

    注:为了简单起见,将FileWriter.txt中的Line2 第二行删除

    public class Client {
        public static void main(String[] args) {
            String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileWriter.txt";
            try {
                //1.创建一个输入流--读取文件
                FileReader fileReader = new FileReader(fileName);
                //2.读取字符
                
                //readOneByOne(fileReader);//一个一个读
                //readOneByWhile(fileReader);//循环一个一个读
                //readByCharArray(fileReader);//字符数组读取
                //readByCharArrayByWhile(fileReader);///字符数组循环读取
                
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    1).read()方法,一次读一个字符
    private static void readOneByOne(FileReader fileReader) throws IOException {
        int ch1 = fileReader.read();
        System.out.println(ch1 + "=" + (char) ch1);//76=L
        int ch2 = fileReader.read();
        System.out.println(ch2 + "=" + (char) ch2);//105=i
        int ch3 = fileReader.read();
        System.out.println(ch3 + "=" + (char) ch3);//110=n
        int ch4 = fileReader.read();
        System.out.println(ch4 + "=" + (char) ch4);//101=e
        int ch5 = fileReader.read();
        System.out.println(ch5 + "=" + (char) ch5);//49=1
        int ch6 = fileReader.read();
        System.out.println(ch6 + "=" + (char) ch6);//32=
        int ch7 = fileReader.read();
        System.out.println(ch7 + "=" + (char) ch7);//31532=第
        int ch8 = fileReader.read();
        System.out.println(ch8 + "=" + (char) ch8);//19968=一
        int ch9 = fileReader.read();
        System.out.println(ch9 + "=" + (char) ch9);//34892=行
        int ch10 = fileReader.read();
        System.out.println(ch10 + "=" + (char) ch10);//-1 //结束标志
    }
    
    read.png
    2).循环读取

    可见一个一个读十分麻烦,既然有结束标识,每次read()都会走到下一个位置,很像迭代器模式

     private static void readOneByWhile(FileReader fileReader) throws IOException {
         int ch = 0;
         while ((ch = fileReader.read()) != -1) {
             System.out.println(ch + "=" + (char) ch);
         }
     }
    

    结果

    76=L
    105=i
    110=n
    101=e
    49=1
    32= 
    31532=第
    19968=一
    34892=行
    
    3).使用字符数组读取
    private static void readByCharArray(FileReader fileReader) throws IOException {
        //字符数组
        char[] buf = new char[8];
        int len = fileReader.read(buf);
        System.out.println("len=" + len + "---->" + new String(buf));
        //len=8---->Line1 第一
        char[] buf2 = new char[8];
        int len2 = fileReader.read(buf2);
        System.out.println("len=" + len2 + "---->" + new String(buf2));
        //len=3---->行\r\n
        char[] buf3 = new char[8];
        int len3 = fileReader.read(buf3);
        System.out.println("len=" + len3 + "---->" + new String(buf3));
        //len=-1---->读完后len为-1
    }
    
    4).使用字符数组循环读取
    private static void readByCharArrayByWhile(FileReader fileReader) throws IOException {
        //字符数组循环读取
        char[] buf = new char[8];
        int len = 0;
        while ((len = fileReader.read(buf)) != -1) {
            System.out.println(new String(buf, 0, len));
            //Line1 第一
            //行
        }
    }
    
    read.png

    二、使用字符流FileWriter和FileReader拷贝文件

    /**
     * 作者:张风捷特烈
     * 时间:2018/10/9 0009:12:47
     * 邮箱:1981462002@qq.com
     * 说明:将 I:\Java\Base\Thinking\src\IOTest\Activity.md
     *      拷贝到 F:\javaTest\IO 文件夹中
     */
    public class Copy {
        public static void main(String[] args) {
            FileWriter fileWriter = null;
            FileReader fileReader = null;
            try {
                //创建一个输出流--写出文件:到F:\javaTest\IO\Activity.md
                fileWriter = new FileWriter("F:\\javaTest\\IO\\Activity.md");
                //创建一个输入流--读取文件:I:\Java\Base\Thinking\src\IOTest\Activity.md
                fileReader = new FileReader("I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md");
                int len = 0;//读取的长度
                char[] buf = new char[1024];//2K的字符数组
                while ((len = fileReader.read(buf)) != -1) {
                    fileWriter.write(buf, 0, len);//写有效个字符
                }
            } catch (IOException e) {
                throw new RuntimeException("读取失败");
            }finally {
                try {//关闭输入流
                    if (fileReader != null) {
                        fileReader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {//关闭输出流
                    if (fileWriter != null) {
                        fileWriter.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    三、字符缓冲:BufferedWriter和BufferedReader

    将字符读入内存缓冲区,避免频繁执行读写操作,提高流的操作效率
    
    默认字符数组缓冲区大小:8192 (即16K的缓冲)
    
    1.BufferedWriter:缓存写出
    BufferedWriter bfw = null;
    try {
        String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\BufferedWriter.txt";
        //1.创建一个输出流--写出文件:需明确被操作文件----文件不存在,会自动创建文件(同名覆盖)
        bfw = new BufferedWriter(new FileWriter(fileName));
        //2.写入数据
        bfw.write("Line1 第一行");
        bfw.newLine();//换行 BufferedWriter特有方法,可区分不同平台换行
        //3.刷新流中的缓冲
        bfw.flush();
        bfw.write("Line2 第二行");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4.关闭流也会刷新缓冲
        try {
            //不为空,才能关闭流
            if (bfw != null) {
                bfw.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    2.BufferedReader:缓存读取
    public static void main(String[] args) {
        String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md";
        try {
            //1.创建一个输入流--读取文件
            BufferedReader  bfr= new BufferedReader(new FileReader(fileName));
            //2.读取字符
            //读取一行:BufferedReader特有方法
            String line = null;
            while ((line = bfr.readLine()) != null) {
                System.out.println(line);
            }
            bfr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    四、效率测试

    通过读取一个1275K的文件看时间消耗情况

    /**
     * 一个一个字符读取测试
     *
     * @param fileName
     * @return
     */
    private static String readOneByOne(String fileName) {
        FileReader fileReader = null;
        try {
            StringBuilder sb = new StringBuilder();
            fileReader = new FileReader(fileName);
            int ch = 0;
            while ((ch = fileReader.read()) != -1) {
                sb.append(new String((new char[]{(char) ch})));
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
        /**
         * 字符数组效率测试
         *
         * @param fileName
         * @return
         */
        private static String readByArray(String fileName) {
            FileReader fileReader = null;
            try {
                StringBuilder sb = new StringBuilder();
                fileReader = new FileReader(fileName);
                int len = 0;
                char[] buf = new char[1024];
                while ((len = fileReader.read(buf)) != -1) {
                    sb.append(new String(buf, 0, len));
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            } finally {
                try {
                    if (fileReader != null) {
                        fileReader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * BufferedReader效率测试
         *
         * @param fileName
         * @return
         */
        private static String readByBuffer(String fileName) {
            BufferedReader bfr = null;
            try {
                StringBuilder sb = new StringBuilder();
                bfr = new BufferedReader(new FileReader(fileName));
                String line = null;
                while ((line = bfr.readLine()) != null) {
                    sb.append(line);
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            } finally {
                try {
                    if (bfr != null) {
                        bfr.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    \ 一个字符 字符数组 BufferedReader
    耗时 0.2798秒 0.1043秒 0.1165秒

    后记:捷文规范

    1.本文成长记录及勘误表
    项目源码 日期 备注
    V0.1--无 2018-10-9 Java中的字符流
    V0.2--无 - -
    2.更多关于我
    笔名 QQ 微信 爱好
    张风捷特烈 1981462002 zdl1994328 语言
    我的github 我的简书 我的CSDN 个人网站
    3.声明

    1----本文由张风捷特烈原创,转载请注明
    2----欢迎广大编程爱好者共同交流
    3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
    4----看到这里,我在此感谢你的喜欢与支持

    相关文章

      网友评论

        本文标题:Java总结IO篇之字符流

        本文链接:https://www.haomeiwen.com/subject/ppcuaftx.html