Java – IO流 – FileWriter字符输出流

简介

FileWriter 是 IO流体系中的字符输出OutputStream的子类,负责 字符流的输出操作,可以把程序中的数据写到本地文本文件中。

 

创建输出流

输出流总体的操作步骤有三步:

1.创建字符输出流对象

2.写出数据

3.释放资源

 

创建对象

创建对象构造方法时,可以传递字符串形式的文件绝对或相对地址,也可以创建一个 File 对象并传入。

// 以字符串形式的绝对或相对路径创建字节流对象,默认清空文件内容再写
public FileWriter(String name);

// 是否追加内容式写入数据(数据续写)
public FileWriter(String name , boolean append)

// 以File对象形式创建字符流对象,默认清空文件内容再写
public FileWriter(File name);

// 是否追加内容式写入数据(数据续写)
public FileWriter(File name , boolean append)

// JDK11 后提供了自定义字符编码写出文件流
public FileWriter(File name , Charset charName)
public FileWriter(File name , Charset charName, boolean append)

注意:

1.参数是字符串表示的路径或者是File对象都可以的

2.如果文件不存在会创建一个新的文件,但是要保证父级文件夹路径是存在的,否则会报出异常

3.如果文件已经存在,则会清空文件,除非调用带有 append 参数的构造函数。

 

写出数据

// 通过写入单个字符的数据到文件中,int 型参数表示要传入的数据为字符对应的字符集码
public void write(int c);

// 通过写入一串字符串数据到文件中
public void write(String str);
// 可以指定这个 字符串 写入的索引和长度
public void write(String str, int off, int len)

// 通过写入字符数组的方式到文件中
public void write(char c[])

// 可以指定这个 char 数组写入的索引和长度
public void write(char c[], int off, int len);

注意:

1.wirte方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符。

2.FileWriter 中的 write 和 FileOutputStream 中的 write 的区别在于,FileWriter 会根据字符个数来写入字节数,如果一个字符的存储量是3个字节,那么使用FileWriter 的 write 写入一个字符将被写入3字节,而 FileOutputStream 中的 write 永远只写出1个字节。

 

释放资源

Java在写文件的时候,会对文件进行占用锁定,期间其它程序无法对它进行操作,因此我们对文件操作完成后,应该要对文件进行解锁去除占用。

fw.close();

 

异常中的处理(普通方式)

FileWriter  中,包含了编译时异常,如果调用FileWriter创建构造时,会出现编译错误,需要我们 throws 抛出异常。

同时也可以使用 try...catch  的方式进行处理。

但是 try...catch  中存在两个问题:

问题一:FileWriter  找不到文件时会直接抛出异常,try 中一旦出现异常时,会停止执行 try 下面的代码,这使得 close()  关闭流这种方法有可能没有执行到。

try {
            // 如果 FileWriter 出现异常,后面的代码不会执行
            FileWriter fw = new FileWriter ("不存在的文件");
            // 这里的代码不会被执行,所以 fw.close() 也不会被执行
            fw.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 如果把 fw.close() 放在这里,则因为作用域的原因,会找不到 fw 对象
            fw.close();
        }

解决方法是,把 FileWriter创建对象移出 try 作用域外

// 把 FileWriter 创建对象移出作用域名,必须初始化为 null,否则 finally 处的 fw.close 会报编译错误
// 原因是,未初始化的对象不能调用 任何 方法
        FileWriter fw = null;
        try {
            // 但因 FileWriter 本身也有编译异常,所以不能在 try 外面 new 
            fw = new FileWriter("不存在的文件");
            // 这里的代码不会被执行,所以 fw.close() 也不会被执行
            fw.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 如果把 fw.close() 放在这里,则因为作用域的原因,会找不到 fw 对象
            fw.close();
        }

问题二:假如,try 中的 FileWriter创建依然报错,那么 fw 对象依然是null ,这时调用 finally 代码块中的 fw.close()  时,依然会报错

// 把 FileWriter 创建对象移出作用域名
        FileWriter fw = null;
        try {
            // 但因 FileWriter 本身也有编译异常,所以不能在 try 外面 new
            fw = new FileWriter("不存在的文件");
            // 这里的代码不会被执行,所以 fw.close() 也不会被执行
            fw.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (fw != null){
                fw.close();
            }
        }

解决方法是:在 调用 close()  方法之前,判断 fw 是否为 null

 

异常中的处理(JDK7方式)

Java 也发现了普通方法中处理 close() 是比较麻烦的,所以在JDK 7 后,提供一个自动关闭文件接口 AutoCloseable 方法,FileWriter实现了 AutoCloseable 接口,我们不需要手动去调用 close()  方法

用法如下

try(定义字节流1; 定义字节流2) {
            fw... 处理逻辑
            fw2... 处理逻辑
}catch (IOException e){
            
}

在JDK7中,try 多出一个小括号,括号中编写定义字节流的方法,多个字节流定义,使用; 进行分割即可。

try(FileWriter fw = new FileWriter("不存在的路径");
     FileWriter fw2 = new FileWriter("不存在的路径")) {
            fw... 处理逻辑
            fw2... 处理逻辑
}catch (IOException e){
            
}

不需要调用 close()  方法

 

异常中的处理(JDK9方式)

从JDK7的方案来看,确实比较好,但是在 try()  中传入创建方法,使得代码非常长,不利于阅读,在JDK9 中,Java 允许创建方法在try()  代码块外面定义,try() 中传个对象即可。

FileWriter fw = new FileWriter("不存在的路径");
FileWriter fw2 = new FileWriter("不存在的路径");
try(fw; fw2) {
            fw... 处理逻辑
            fw2... 处理逻辑
}catch (IOException e){
            
}

多个对象,依然使用 ; 分割即可。

 

FileWriter底层原理

1.当创建FileWriter对象时,对象内部会生成一个 byte[8192] 的数组。

2.当调用第一次 write() 方法时,FileWriter 会往 byte[8192] 数组中填入数据。

3.当 byte[8192] 数组被填满后,FileWriter 会把数组中的数据写出到文本文件中,当再次写数据时,不会马上写到文件中,而是再一次存放到 byte[] 数组中。

4.或当填入数据后(数组未被填满的情况下),调用 flush() 刷新方法,FileWriter 会立即把数据写到文件中,flush() 方法只负责把数据即时写到文本文件中,不会关闭文件流。

5.当 close() 方法被调用后,FileWriter 也会把仅存在的 byte[] 中剩下的数据写出到文本文件中,并关闭文件流。

注意:FileOutputStream 中的 write() 不具有 byte[] 数据缓冲机制。

 

换行与续写

换行

在不同的操作系统中,换行符也不一样

1.Windows 中的换行符为 \r\n

2.Linux 中的换行符为 \n

3.MacOS 中的换行符为 \r

在Java中,换行符的问题已经做了优化补全,所以即使使用 \n  也可以实现换行

String wrap = "\r\n";
fw.write(wrap.getBytes());
fw.write("\r\n"); // 直接使用字符串

续写

FileWriter 在创建对象中,包含了续写的构造函数

FileWriter fw = new FileWriter("path", true);

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

THE END
分享
二维码
打赏
海报
Java – IO流 – FileWriter字符输出流
简介 FileWriter 是 IO流体系中的字符输出OutputStream的子类,负责 字符流的输出操作,可以把程序中的数据写到本地文本文件中。   创建输出流 输出流总体的操作步骤有三步: 1.创建字符……
<<上一篇
下一篇>>