前言

前面我们已经针对字符输入流进行了解,那么既然有字符输入流,反过来就肯定有字符输出流,那么就让我们进入字符输出流的世界吧!

字符输出流(Writer)

java.io.Writer抽象类是字符输出流的所有类的超类(父类),将指定的字符信息写出到目的地。它同样定义了字符输出流的基本共性功能方法。

字符输出流的基本共性功能方法:

IO之字符输出流

FileWriter类

IO之字符输出流
还是老规矩,只聊聊最简单的FileWriter类
java.io.FileWriter类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

构造方法

IO之字符输出流
依旧是熟悉的构造举例,代码如下:

public class FileWriterConstructor {
    public static void main(String[] args) throws IOException {
        // 第一种:使用File对象创建流对象
        File file = new File("a.txt");
        FileWriter fw = new FileWriter(file);

        // 第二种:使用文件名称创建流对象
        FileWriter fw = new FileWriter("b.txt");
    }
}

FileWriter写出数据
写出字符:write(int b) 方法,每次可以写出一个字符数据,代码使用演示:

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");     
        // 写出数据
        fw.write(97); // 写出第1个字符
        fw.write('b'); // 写出第2个字符
        fw.write('C'); // 写出第3个字符

        //关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。
        // fw.close();
    }
}
输出结果:
abC

注意

关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。

关闭close和刷新flush

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。

flush :刷新缓冲区,流对象可以继续使用。
close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

flush还是比较有趣的,如果不自己运行一下还真不好体会,现在就举个列子大家体会体会:

public class FlushDemo {
    public static void main(String[] args) throws Exception {
        //源   也就是输入流【读取流】 读取a.txt文件
        FileReader fr=new FileReader("a.txt");  //必须要存在a.txt文件,否则报FileNotFoundException异常
        //目的地  也就是输出流
        FileWriter fw=new FileWriter("b.txt");  //系统会自动创建b.txt,因为它是输出流!
        int len;
        while((len=fr.read())!=-1){
           fw.write(len);
        }
   注意这里是没有使用close关闭流,开发中不能这样做,但是为了更好的体会flush的作用
    }
}

IO之字符输出流

运行效果是怎么样的呢?答案是b.txt文件中依旧是空的,是的并没有任何东西,为啥呢?我在上面就用红色字体特别标注过了,就是这句话: 【注意】关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。
所以,我们在以上的代码中再添加下面三句代码,就完美了,b.txt文件就能复制到源文件的数据了!

  fr.close();
  fw.flush();
  fw.close();

flush()这个函数是清空的意思,用于清空缓冲区的数据流,进行流的操作时,数据先被读到内存中,然后再用数据写到文件中,那么当你数据读完时,我们如果这时调用close()方法关闭读写流,这时就可能造成数据丢失,为什么呢?因为,读入数据完成时不代表写入数据完成,一部分数据可能会留在缓存区中,这个时候flush()方法就格外重要了。

好了,接下来close使用代码如下:

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");
        // 写出数据,通过flush
        fw.write('刷'); // 写出第1个字符
        fw.flush();
        fw.write('新'); // 继续写出第2个字符,写出成功
        fw.flush();

        // 写出数据,通过close
        fw.write('关'); // 写出第1个字符
        fw.close();
        fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed
        fw.close();
    }
}

即便是flush方法写出了数据,操作的最后还是要调用close方法,释放系统资源。

FileWriter的续写和换行

续写和换行:操作类似于FileOutputStream操作(上一篇博客讲到过),直接上代码:

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象,可以续写数据
        FileWriter fw = new FileWriter("fw.txt",true);     
        // 写出字符串
        fw.write("哥敢");
        // 写出换行
        fw.write("\r\n");
        // 写出字符串
        fw.write("摸屎");
        // 关闭资源
        fw.close();
    }
}
输出结果:
哥敢
摸屎

结束

本篇主要是真丢字符输出流进行针对性的细聊,怎么说呢,字符输入流和字节输入流有很多的相似之处,但是也有一些不同,所以需要大家仔细体会一下,如果说一些地方不明白,可以往前面看看字节输出流的内容