基本文件字符流FileWriter、FileReader

详细介绍了Java IO中的基本文件字符流FileWriter、FileReader的方法以及使用方式。

1. IO流概述

IO,即输入和输出。流,即数据的传输,可以看做是一种数据的流动。

按照流动的方向,以内存为基准,分为输入input 和输出output ,即流向内存是输入流,流出内存的输出流,合称IO流。

Java中流的分类:

  1. 按数据流向:
    1. 输出流:将内存中的数据流向到外部的介质。
    2. 输入流:将外部介质的数据流向内存。
  2. 按数据类型:
    1. 字节流:处理数据单位是字节,1Byte。
    2. 字符流:处理数据单位是字符,2Byte。
  3. 流动方向与操作相结合:
    1. 字节输入流: InputStream类
    2. 字节输出流: OutputStream类
    3. 字符输入流: Reader类
    4. 字符输出流: Writer类

以上四类都在IO包中,都是顶级抽象类。

2 FileWriter文件字符输出流

public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable

特点:

  1. 输出到外部。
  2. 输出的是字符,只能操作文本。
  3. 作为各个字符输出类的最终抽象基类。所有子类必须实现的方法有 write(char[], int off, int length)、flush() 和 close()。
public class FileWriter
extends OutputStreamWriter

和文件相关的字符输出流,文件的输出。用来写入字符文件的便捷类。用于写入字符流。
在这里插入图片描述

2.1 构造器

  FileWriter(String fileName)  

根据给定的文件名构造一个 FileWriter 对象。filename:String类型的要写入的文件路径。

注意:

  1. 创建该对象的时候,必须指定一个抽象路径
  2. 如果指定的文件不存在,将会自动的创建。
  3. 如果文件存在,会把原来的文件替换。
FileWriter(String fileName, boolean b);

根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。filename:要写入的文件路径。b:当指定的boolean 值为true,在原有文件的基础上实现续写。

public FileWriter(File file);

根据给定的 File 对象构造一个 FileWriter 对象。

public FileWriter(File file,boolean append);

根据给定的 File 对象构造一个 FileWriter 对象。以及指示是否附加写入数据的 boolean 值确定是将字符写入文件末尾处还是写入文件开始处。

创建输出流到底做了哪些事情?

  1. 调用系统功能去创建文件。
  2. 创建输出流对象。
  3. 把输出流对象指向这个文件。

2.2 API方法

它的方法全部从直接父类OutputStreamWriter和间接父类Writer、Object继承。

public void write(int c);  

写入单个字符,要写入的字符包含在给定整数值的16个低位中,16高位被忽略。(底层Int类型的C—>32位二进制数—>保留低位16位—>转换为char类型)

public void write(String str);  

写入字符串。

public void write(String str,int off,int len);  

写入字符串的某一部分。str:字符串。off:相对初始写入字符的偏移量。len:要写入的字符数。

public void write(char[] cbuf)

写入字符数组。

public abstract void write(char[] cbuf,int off,int len);

写入字符数组某一部分。cbuf:要写入的数组。off:开始写入字符处的偏移量。len:要写入的字符数。

public abstract void flush();

刷新流的缓冲。

public abstract void close();

将流资源关闭。

public String getEncoding(); 

返回该流使用的字符编码名称。

2.1.1 补充

flush:刷新流的缓冲,流资源没有关闭,资源可以继续使用。

close:将流资源直接关闭。在关闭之前,会自动调用一次flush方法。流资源一旦关闭,不能在次被使用。

为什么一定要close()呢?

  1. 让流对象变成垃圾,这样就可以被垃圾回收器回收了
  2. 通知系统去释放跟该文件相关的资源,否则文件句柄等资源会被一直占用,而Java的GC只会回收对象,不会回收相关文件资源。

3 FileReader文件字符输入流

public abstract class Reader
extends Object
implements Readable, Closeable

Reader :字符输入流,用于读取字符流的抽象超类。子类必须实现的方法只有 read(char[], int off, int length) 和 close()。

public class FileReader
extends InputStreamReader

FileReader,和文件相关的字符输入流,可用于读取文件数据。创建对象的时候,如果指定的文件不存在,将抛出异常。
在这里插入图片描述

3.1 构造器

public FileReader(String fileName)
           throws FileNotFoundException

在给定从中读取数据的文件名的情况下创建一个新 FileReader。

public FileReader(File file)
           throws FileNotFoundException

在给定从中读取数据的 File 的情况下创建一个新 FileReader。

public FileWriter(File file, boolean append)
           throws IOException

根据给定的 File 对象构造一个 FileWriter 对象。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。即,追加写入而不是覆盖写入。

3.2 API方法

它的方法全部从直接父类InputStreamReader和间接父类Reader、Object继承。

public int read(); 

一次读取一个字符。返回int类型,如果读取到末尾,返回-1,可以做为循环条件判断结束依据使用。

public int read(char[] cbuf);  

将读取的数据存放在字符数组当中,返回的是已读取字符个数,读取的字符数,如果已到达流的末尾,则返回 -1.可以做为循环条件判断结束依据使用。

new String(cbuf,0,read); 转换字符数组。建议:尽量用读取数组的方法来读取数据,可以避免内存与外部介质的频繁交互。

close();

关闭流资源。

3.2.1 补充

为什么read()方法要使用int类型变量来接收返回值呢?

FileReader 的 read 方法返回值是一个int类型的变量来接收的,而read方法在实际中却是以字符形式来进行数据的读取的。返回的是作为整数读取的字符,即返回Unicode码,其范围在 0 到 65535 之间 (0x00-0xffff),也就是说char类型数据是取不到负值的;

int类型数据的取值范围为-2147483648-2147483647,可以取到负值;同时 int 的取值范围又包含 char 的取值范围,这就为使用 int 作为返回值类型提供了可能,因为流需要一个特殊的值来表示流末尾,这个值不应该在 char 的取值范围内,如果使用 char 取值范围内的值作为流末尾标志,那么这个值同样有可能出现在数据流中间作为数据来传输,流在读到这个值的时候会认为已经到达流末尾,后面未读取的数据将被截断。

所以 Java 中选择了使用-1来作为流末尾,这个值不在char的取值范围内,所以不存在数据截断,然而-1又在 int 的取值范围内,同时int的取值范围包含 char的取值范围,所以FileReader下read方法返回的char类型数据直接转为了 int类型。

4 案例

4.1 写入文件

利用Filewriter将字符写入到指定文件中。

public class FilewriterDemo01 {
    @Test
    public void Test1() throws IOException {
        FileWriter file = null;
        try {
            file = new FileWriter("C:\\Users\\lx\\Desktop\\test.txt");
            file.write("呵呵");
            file.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file != null) {
                file.close();
            }
        }
    }

    @Test
    public void Test2() throws IOException {
        FileWriter file = null;
        try {
            file = new FileWriter("C:\\Users\\Administrator\\Desktop\\a.txt",
                    true);
            file.write("\r\n呵呵");
            file.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file != null) {
                file.close();
            }
        }
    }
}

4.2 读取文件

利用Filewriter从指定文件中获取字符数据。注意文件应该使用UTF-8编码,否则可能出现乱码。

public class FileReaderDemo01 {
    public static void main(String[] args) throws IOException {
        FileReader file = null;
        try {
            file = new FileReader("C:\\Users\\lx\\Desktop\\test.txt");
      /* int read = 0;
         while ((read = file.read()) != -1)
         {
            System.out.print((char) read);
         }*/
            char[] ch = new char[1024];
            int read = 0;
            while ((read = file.read(ch)) != -1) {
                System.out.println(new String(ch, 0, read));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file != null) {
                file.close();
            }
        }
    }

}

4.3 拷贝文件

注意文件应该使用UTF-8编码,否则可能出现乱码。

利用FileReader和FileWriter实现文件数据的拷贝。

public class Copy {
    public static void main(String[] args) throws IOException {
        FileWriter filew = null;
        FileReader filer = null;

        try {
            filer = new FileReader("C:\\Users\\lx\\Desktop\\test.txt");
            filew = new FileWriter("C:\\Users\\lx\\Desktop\\target.txt");
         /*int read=0;
         while ((read=filer.read())!=-1)
         {
            filew.write((char)read);
         }*/
            int read = 0;
            char[] ch = new char[1024];
            while ((read = filer.read(ch)) != -1) {
                filew.write(new String(ch, 0, read));
            }
            filew.flush();
        } catch (Exception e) {
            throw new RuntimeException("IO异常");
        } finally {
            if (filer != null) {
                filer.close();
            }
            if (filew != null) {
                filew.close();
            }
        }
    }

}

如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值