Java IO流之字符流,带缓冲的字符流

IO流

看着字少,内容着实不少,这里开始就给诸君推荐一篇大神的博客,总结的思路清晰,鬼斧神工,哈哈,总之总结的很好。见地址:

Java IO流学习总结,也是很好的入坑引言。

Java IO流学习总结
Java IO流学习总结
Java IO流学习总结
写三次应该有人会传送过去的吧。

IO分类

  • 按数据类型分为字符流,字节流。
  • 按数据流向分为输入流,输出流。

输入字节流(InputStrem) 输出字节流(OutputStrem) 字符输入流(Reader) 字符输出流(Writer)

我们先看字符输出流Writer。

字符输出流----Writer

要了解它,它却很抽象,孤僻,难以交流,那我们就从它子子孙孙开始。首先我们看它孙子FileWriler。

FileWriter 继承自OutputStreamWriter

构造方法:

     //创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。
     public FileWriter(String var1) throws IOException {
            super(new FileOutputStream(var1));
        }//如:FileWriter fw=new FileWriler("D:files.txt");

      //创建字符输出流类对象和已存在的文件相关联,并设置该该流对文件的操作是否为续写。
     public FileWriter(String var1, boolean var2) throws IOException {
            super(new FileOutputStream(var1, var2));
        }//如:FileWriter fw=new FileWriler("D:files.txt",true);//true表示再次写入字符的时候为追加,false表示再次写入字符时,先擦除,在写入(覆盖)

      //类似构造方法一
     public FileWriter(File var1) throws IOException {
            super(new FileOutputStream(var1));
        }//如:FileWriter fw=new FileWriter(new File("D:files.txt"));

      //类似构造方法二
     public FileWriter(File var1, boolean var2) throws IOException {
            super(new FileOutputStream(var1, var2));
        }//如:FileWriter fw=new FileWriter(new File("D:files.txt"),flase);//覆盖写入

      //不常用
      public FileWriter(FileDescriptor var1) {
            super(new FileOutputStream(var1));
        }//如:

可见构造方法都抛异常的,忘了告诉你,上面的已经是FileWriter所有的代码了。

主要方法:
  • void write(String str)写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲区中。
    此时在使用刷新方法就可以使数据保存到目的文件中去。

  • void flush() 刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中。

  • void close() 关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常。

案例
    /**
     * IO流代码很难看,主要是因为异常处理过多
     */
    public class Demo {
        public static void main(String[] args) {
            FileWriter writer = null;
            FileWriter writer1 = null;

            FileWriter writer2 = null;
            FileWriter writer3 = null;
            try {
                //1. 创建FileWriter对象,并在构造方法中指定文件路径
                writer = new FileWriter(Config.PATH + "testFileWriter1.txt");//此文件是在当前工程目录下
                //2.向文件字符中写入一串文本数据
                writer.write("hello");
                writer.flush();//3、在关闭流之前,先执行刷新//刷一次代表写入一次

                //构造方法的第二个参数,表示是否追加内容
                writer1 = new FileWriter(Config.PATH + "testFileWriter1.txt");//写入的新的内容会在原内容的后面增加
                writer1.write("你好-->1");
                writer1.flush();

                //构造方法的第二个参数,表示是否追加内容
                writer2 = new FileWriter(Config.PATH + "testFileWriter2.txt");
                writer2.write("你好-->2");
                writer2.flush();

                //构造方法的第二个参数,表示是否追加内容 true 追加 false 覆盖
                writer3 = new FileWriter(Config.PATH + "testFileWriter2.txt", false);//写入的新的内容会覆盖原内容
                writer3.write("你好-->");
                writer3.flush();
                writer3.write("猪");
                writer3.flush();

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    writer.close(); //关闭流
                    writer1.close();
                    writer2.close();
                    writer3.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • Config中的代码

      public static final String PATH = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series10/src/main/java/files/";
    
结果

说明默认写入模式为覆盖。

字符输入流----Reader

同样的看他孙子类。

FileReader 继承自InputStreamReader

构造方法,也是所有源码

    //使用带有指定文件的String参数的构造方法。创建该输入流对象。并关联源文件。
    public FileReader(String var1) throws FileNotFoundException {
            super(new FileInputStream(var1));
        }//如:FileReader fr = new FileReader(String file);
    //基本同构造方法一,因为构造方法一传的String 目的也是创建一个文件
    public FileReader(File var1) throws FileNotFoundException {
            super(new FileInputStream(var1));
        }//如:FileReader fr = new FileReader(new File(str));//str为String类型

    //不常用
    public FileReader(FileDescriptor var1) {
            super(new FileInputStream(var1));
        }//如:
主要方法:
  • void read()读取单个字符。返回作为整数读取的字符,如果已达到流末尾,则返回 -1。

  • void read(char[]char) 将字符读入数组。返回读取的字符数。如果已经到达尾部,则返回-1。

  • void close() 关闭此流对象。释放与之关联的所有资源

案例----我们把上一个案例的testFileWriter2.txt文件内容读出来
    public class Demo {
        public static void main(String[] args) {
            //1.声明FileReader对象
            FileReader fileReader = null;
            try {
                //2. 实例化FileReader对象
                fileReader = new FileReader(Config.PATH + "testFileWriter2.txt");//可能会抛出FileNotFoundException异常
                //3.文本读取
                int num = 0;
                while ((num = fileReader.read()) != -1) {//每次读一个字符,如果为-1表示已到文件结束位置
                    System.out.print((char) num);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fileReader.close();//关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
结果
案例----演示void read(char[]char) 用法
    public class Demo {
        public static void main(String[] args) {
            FileReader fileReader = null;
            try {
                fileReader = new FileReader(Config.PATH + "testFileWriter2.txt");
                char[] buffer = new char[4];//每次最多读4个字符
                int n = 0;
                while ((n = fileReader.read(buffer)) != -1) {//每次最多读4个字符,如果为-1表示已到文件结束位置
                    //打印本次读取的内容,从0位置开始,到本次读取的字符个数
                    System.out.println("读取 "+n+"个字符: "+new String(buffer,0,n));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
结果

可见读取到的内容都是一样的。

字符流(FileReader FileWriter)复制文件案例

    /**
     * 需求:copy拷贝 Demo1文件
     * 思路:肯定是边读边写
     */
    public class Demo {
        //源文件路径
        public static final String PATH = "/Volumes/huang/studyfromGitHub/JavaForAndroid/JavaForAndroid/series10/src/main/java/com/example/Demo1.java";
        public static final String FILENAME = "copyDemo1.java";

        public static void main(String[] args) {
            // 1. 声明文件字符的输入、输出流对象
            FileReader fileReader = null;
            FileWriter fileWriter = null;

            try {
                // 2. 实例化流操作对象
                fileReader = new FileReader(PATH);
                fileWriter = new FileWriter(Config.PATH + FILENAME);//如果文件不存在,则会自动创建
                char[] buffer = new char[6];
                int len = 0;
                while ((len = fileReader.read(buffer)) != -1) {//边读
                    fileWriter.write(buffer, 0, len);//边写,将本次读取的字符写入到复制的文件中
                }

            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    //最后别忘了关闭流
                    fileReader.close();
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
结果

标红不是我的错,本来就该标红。

字符输出流使用缓冲----FileWriter和BufferedWriter

  • FileWriter 文件字符输出流
  • BufferedWriter 缓冲字符输出流
BufferedWriter缓冲字符输出流,直接继承自Writer

构造方法

public BufferedWriter(Writer var1) {
        this(var1, defaultCharBufferSize);
    }

public BufferedWriter(Writer var1, int var2) {
        super(var1);
        if(var2 <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        } else {
            this.out = var1;
            this.cb = new char[var2];
            this.nChars = var2;
            this.nextChar = 0;
            this.lineSeparator = (String)AccessController.doPrivileged(new GetPropertyAction("line.separator"));
        }
    }

没看错的话是两个,要想得到BufferedWriter实例,必须给它传一个Writer实例。

运用举例
public class Demo{
    public static final String NAME = "testDemo5.txt";

    public static void main(String[] args) {
        //1.变量声明
        FileWriter fileWriter = null;
        BufferedWriter bufferedWriter = null;

        try {
            //2.实例化变量
            fileWriter = new FileWriter(Config.PATH + NAME);
            bufferedWriter = new BufferedWriter(fileWriter);//装饰者模式,扩展现有功能(包装),将节点流(文件字符流)对象作为构造参数使用
            //通过缓冲流对象向文本文件中写入数据
            bufferedWriter.write("哈哈,");
            bufferedWriter.newLine();//换行
            bufferedWriter.write("此处发现一个大傻逼。");
            //此处追加文本数据是向缓冲追加,而非是将内容追加到文件内
            bufferedWriter.append("追加内容")
                    .append("\r\n").append("这里也有一个傻逼。");
            //注:缓冲数据是将数据存入内存中,并没有写入到文件中,在关闭流之前必须要执行flush()方法
            bufferedWriter.flush();//将内存的数据写入到文件中
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedWriter.close();//处理流关闭之后,节点流会自动关闭
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
结果

注:缓冲数据是将数据存入内存中,并没有写入到文件中,在关闭流之前必须要执行flush()方法。
大家有没有发现FileWriter被BufferedWriter包装之后,功能变多了。。。下一篇让我们来稍微了解一下装饰者模式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容