前面一章介绍了字节流的使用,提到了字节流在处理utf-8编码的中文可能会出现乱码的情况(其他编码的中文同样会出现乱码),所以Java针对这一情况提供了字符流。

但是字符流只能处理字符,不能用来处理 .jpg;.mp3;.mp4;.avi;.doc;.ppt等二进制文件,这些只能通过字节流来处理。所以对于纯文本的文件,强烈推荐使用字符输入输出流。

字符流的本质其实就是基于字节流在读取时去查了指定的码表。

1、字符输入流Reader

Reader是所有字符输入流的父类,定义了所有字符输入流都具有的共同特征。其内部提供的方法如下:

上图中重载的三个read()方法都是用来读数据的。

  • int read():每次读取一个字符,并把它转换为 0~65535 的整数,然后返回读取到的字符。读到末尾返回-1。(为了提高 I/O 操作的效率,建议尽量使用下面两种read()方法)
  • int read(char[] cbuf):将读取到的多个字符存储到 cbuf 中,然后返回读取的字符,读到末尾时返回-1。
  • int read(char[] cbuf,int off,int len):将读取到的多个字符存储进字符数组 cbuf,从索引 off 开始,长度为len字符,返回结果为读取的字符数.

其中Reader的子类FileReader是专门用于读取文件中的数据,通过它将目标设备上的数据读入到程序。

FileReader读入文件举例(读取的hello.txt文件内容是:你好,我是中国人!):

package com.thr;

import java.io.File;
import java.io.FileReader;
import java.io.IOException; /**
* @author Administrator
* @date 2020-02-23
* @desc 字符输入流FileReader
*/
public class FileReaderTest { public static void main(String[] args) {
//定义输入流
FileReader fr =null;
try {
//1、创建文件对象
File file = new File("D:\\IO\\hello.txt");
//2、创建输入流对象
fr = new FileReader(file); //循环读取,读取到末尾返回-1
int len ;//记录每次读取的字节个数
while((len = fr.read())!=-1){
System.out.print((char)len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
你好,我是中国人!

2、字符输出流Writer

Writer是所有字符输出流的父类,定义了所有字符输出流都具有的共同特征。其内部提供的方法如下:

上图中重载的五个write()方法都是用来写数据的。

  • void write(int c):把一个字符写入到文件中。

  • void write(char[] cbuf):把cbuf字符数组写入到文件中。
  • void write(char[] cbuf,int off,int len):把部分字符数组写入到文件中,从 cbuf 数组的 off 索引开始,写入len个字符。
  • void write(String str):把一个字符串写入到文件中。
  • void write(String str,int off,int len):把部分字符串写入到文件中,从 字符串的 off 索引开始,写入len个字符。

其中Writer的子类FileWriter是门用于读出文件中的数据,通过它将数据从程序输出到目标设备。

FileWriter输出文件举例:

package com.thr;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException; /**
* @author Administrator
* @date 2020-02-23
* @desc 字符输出流FileWriter
*/
public class FileWriterTest { public static void main(String[] args) {
//定义输出流
FileWriter fw =null;
try {
//1、创建文件对象
File file = new File("D:\\IO\\a.txt");
//2、创建输出流对象,保留原来的数据,在文件后面追加
fw = new FileWriter(file,true); //write():写出一个字符(utf-8编码)
fw.write(20200223);
fw.write("\r\n");//回车换行 //write(char[] buffer):把cbuf字符数组写入到文件中。
fw.write("我是中国人".toCharArray());
fw.write("\r\n"); //write(char[] cbuf,int off,int len):把部分字符数组写入到文件中,从 cbuf 数组的 off 索引开始,写入len个字符。
fw.write("我是中国人".toCharArray(),1,4);
fw.write("\r\n"); //write(String str):把一个字符串写入到文件中。
fw.write("中国人");
fw.write("\r\n"); //write(String str,int off,int len):把部分字符串写入到文件中,从 字符串的 off 索引开始,写入len个字符。
fw.write("你好,我是中国人\n",3,6); } catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

注意:如果字符输出流不调用close()方法关闭资源,数据只是保存到缓冲区,并不会保存到文件(这一点与FileOutputStream不同,即使它不调用close()方法依然会写入到文件中)。

这里就得介绍一下flush()这个方法。

flush()和close()方法的区别:

flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。

close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。

而当我们亲自去使用flush()方法的时候会产生一个疑问,就算我们在close()之前不加flush()方法也不会影响文件的写出呀,那为什么还要用这个方法呢?先看一下下面的代码吧:

package com.thr;

import java.io.FileWriter;
import java.io.IOException; /**
* @author Administrator
* @date 2020-02-24
* @desc flush方法的使用
*/
public class WriterFlushTest { public static void main(String[] args) { //定义输出流
FileWriter fw = null; //其实该步就是在明确数据要存放的目的地
try {
fw=new FileWriter("D:\\flush.txt");
fw.write("介");//调用write方法,将字符串写入到流中(使用write其实并没有将字符串直接写入到指定文件,而是存放在流中)
fw.flush();//这一步才是将上一步write的所写的字符串冲刷到指定的文件(在指定的文件打开后有字符串存在了) fw.write("绍");
fw.flush(); fw.write("flush方法");
fw.flush(); fw.close();//close()是一定要做的(其实close方法中调用了flush方法) fw.write("CCC");//close后若再write,会提示IO异常Stream closed } catch (IOException e) {
e.printStackTrace();
}
}
}

小声BB:我认为flush()方法可有可无,它就是将缓冲区的数据强制写入到文件中,因为在调用完write()方法后数据并没有写入到文件中,而是保存在流中,此时我们可以调用flush()方法,也可以在最后用close()方法来将数据写入文件,因为在close()的时候,也会进行一次flush的,因此close之前其实可以不用专门做flush的。但是在某些情况下,数据量较大的时候,在写的过程中,可以进行阶段性的flush。(话说我也不知道这样做会有什么好处……

3、字符流拷贝文件

package com.thr;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; /**
* @author Administrator
* @date 2020-02-23
* @desc 拷贝文本文件
*/
public class FileReaderWriterTest { public static void main(String[] args) {
//定义输入流
FileReader fr =null;
//定义输出流
FileWriter fw =null;
try {
//创建读入文件对象
File f1 = new File("D:\\IO\\hello.txt");
//创建读出文件对象
File f2 = new File("C:\\a.txt"); fr = new FileReader(f1);
fw = new FileWriter(f2); //循环读取,读取到末尾返回-1
char chars[] = new char[1024];
int len ;//记录每次读取的字节个数
while((len = fr.read(chars))!=-1){
fw.write(chars,0,len);
}
System.out.println("拷贝成功...");
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
try {
fr.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Java IO流详解(四)——字符流Reader和Writer的更多相关文章

  1. Java IO(十二) 字符流 Writer 和 Reader

    Java IO(十二) 字符流 Reader和 Writer 一.介绍 涉及到文件(如果是纯文本文件形式)操作时,Java除了提供 FIle(文件和目录路径名的抽象表示形式) 和 FileDescri ...

  2. JAVA IO 类库详解

    JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...

  3. Java IO最详解

    初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见 ...

  4. Java io流详解四

    转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...

  5. java IO(五):字节流、字符流的选择规律

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  6. Linux 网络编程详解四(流协议与粘包)

    TCP/IP协议是一种流协议,流协议是字节流,只有开始和结束,包与包之间没有边界,所以容易产生粘包,但是不会丢包. UDP/IP协议是数据报,有边界,不存在粘包,但是可能丢包. 产生粘包问题的原因 . ...

  7. Java面试题详解四:==和equals的去别

    一,功能 1.对于== 作用于基本数据类型的变量,比较的存储的值是否相等, 作用于引用类型的变量,比较的是其所指向的对象的地址是否相同(即是否是同一个对象) 2.对于equals Object的equ ...

  8. Mac下Intellij IDea发布Java Web项目详解四 为所有Module配置Tomcat Deployment

    准备工作1:新建第一个JavaWeb项目 准备工作2:新建Module step5 为所有项目配置Deployment 5.1 如图 5.2 [+][Artifact] 5.3 将这里列出的所有内容选 ...

  9. [转载] java多线程学习-java.util.concurrent详解(四) BlockingQueue

    转载自http://janeky.iteye.com/blog/770671 ------------------------------------------------------------- ...

  10. Mac下Intellij IDea发布Java Web项目详解五 开始测试

    测试前准备工作目录 Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intell ...

随机推荐

  1. MP4文件格式分析及分割实现(附源码)

    MP4文件格式分析                   MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在“ISO/IEC 14496-14”标准文件中定义的,属于MPEG-4的 ...

  2. mvc:annotation-driven的前缀 "mvc"未绑定

    缺少MVC的配置,正确配置如下: <beans xmlns="http://www.springframework.org/schema/beans"       xmlns ...

  3. docker镜像 - 下载、创建镜像和导入导出镜像

    实验环境 CentOS 7.5 安装并启动docker yum install -y docker systemctl start docker 镜像 安装镜像 docker pull [OPTION ...

  4. [Python]python中assert和isinstance的用法

    assert语句是一种插入调试断点到程序的一种便捷的方式. assert == assert == True assert ( == ) print('-----------') assert ( = ...

  5. Python - 将iterable拆分成等长的数据块

    说明 看文档发现一个有趣的应用(利用zip函数) 例如[1, 2, 3, 4] --> [(1, 2), (3, 4)],拆分成长度为2的数据块 Code >>> a = [1 ...

  6. varchar(n)

    MySQL5.0.3之前varchar(n)这里的n表示字节数MySQL5.0.3之后varchar(n)这里的n表示字符数,比如varchar(200),不管是英文还是中文都可以存放200个根据字符 ...

  7. C#委托和事件的区别

    “委托是具有相同签名的函数(方法)的类型,事件是委托的应用方式之一” ---来自评论区老司机 delegate 是为了在C#中把函数作为对象传来传去而实现的一个“函数包装”.由于在C#中函数是二等公民 ...

  8. Hadoop架构: 流水线(PipeLine)

    该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 流水线(PipeLine),简单地理解就是客户端向DataNode传输数据(Packet)和接收Dat ...

  9. Git储藏工作现场

    假设你现在在dev分支工作,此时你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,你当前工作只进行到一半,还没法提交,预计完成还需1天时间 ...

  10. 吴裕雄 PYTHON 人工智能——基于MASK_RCNN目标检测(5)

    import os import sys import numpy as np import tensorflow as tf import matplotlib import matplotlib. ...