Java IO流详解(四)——字符流Reader和Writer
前面一章介绍了字节流的使用,提到了字节流在处理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的更多相关文章
- Java IO(十二) 字符流 Writer 和 Reader
Java IO(十二) 字符流 Reader和 Writer 一.介绍 涉及到文件(如果是纯文本文件形式)操作时,Java除了提供 FIle(文件和目录路径名的抽象表示形式) 和 FileDescri ...
- JAVA IO 类库详解
JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...
- Java IO最详解
初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见 ...
- Java io流详解四
转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...
- java IO(五):字节流、字符流的选择规律
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- Linux 网络编程详解四(流协议与粘包)
TCP/IP协议是一种流协议,流协议是字节流,只有开始和结束,包与包之间没有边界,所以容易产生粘包,但是不会丢包. UDP/IP协议是数据报,有边界,不存在粘包,但是可能丢包. 产生粘包问题的原因 . ...
- Java面试题详解四:==和equals的去别
一,功能 1.对于== 作用于基本数据类型的变量,比较的存储的值是否相等, 作用于引用类型的变量,比较的是其所指向的对象的地址是否相同(即是否是同一个对象) 2.对于equals Object的equ ...
- Mac下Intellij IDea发布Java Web项目详解四 为所有Module配置Tomcat Deployment
准备工作1:新建第一个JavaWeb项目 准备工作2:新建Module step5 为所有项目配置Deployment 5.1 如图 5.2 [+][Artifact] 5.3 将这里列出的所有内容选 ...
- [转载] java多线程学习-java.util.concurrent详解(四) BlockingQueue
转载自http://janeky.iteye.com/blog/770671 ------------------------------------------------------------- ...
- Mac下Intellij IDea发布Java Web项目详解五 开始测试
测试前准备工作目录 Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intell ...
随机推荐
- 在网页中插入背景音乐代码(html)
有两种 分别用<bgsound>和<embed></embed>标签,当用<embed>插入背景音乐时可以设置宽度和高度为0,隐藏播放器. 二者的参数如 ...
- Makefile中的wildcard/notdir/patsubst
在Makefile规则中,通配符会被自动展开. 但在变量的定义和函数引用时,通配符将失效.这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTE ...
- 条件锁condition与Queue()
在学习之前你应该先了解锁和队列基础 import queue import time import random import threading import asyncio import logg ...
- Vue - 动态组件 & 异步组件
动态组件 <div id="app"> <components :is="com[2]"></components> < ...
- PHP 超全局变量之$GLOBALS
$GLOBALS——引用全局作用域中可用的全部变量. $GLOBALS一个包含了全部变量的全局组合数组.变量的名字就是数组的键.(即所有出现过的全局变量,都可通过$GLOBALS获取到) 注释: “S ...
- Flask 教程 第十九章:Docker容器上的部署
本文翻译自The Flask Mega-Tutorial Part XIX: Deployment on Docker Containers 这是Flask Mega-Tutorial系列的第十九部分 ...
- Loppinha, the boy who likes sopinha Gym - 101875E (dp,记忆化搜索)
https://vjudge.net/contest/299302#problem/E 题意:给出一个01 0101串,然后能量计算是连续的1就按1, 2, 3的能量加起来.然后给出起始的能量,求最少 ...
- vue 对象数组中,相邻的且相同类型和内容的数据合并,重组新的数组对象
在项目中,有时候会遇到一些需求,比如行程安排,或者考勤状态.后台返回的获取是这一周的每一天的状态,但是我们前端需求显示就是要把相邻的且状态相同的数据进行合并,所以我们就要重新组合返回的数据.如下所示: ...
- 在MyEclipse2017中配置JDK和Tomcat8.5
在MyEclipse2017中配置Tomcat8.5: 首先,确保你已安装好JDK.Tomcat等 1.启动MyEclipse后,点击菜单栏的"Window": 2.为MyEcli ...
- 数星星 Stars
问题 A: 数星星 Stars 时间限制: 1 Sec 内存限制: 128 MB[命题人:admin] 题目描述 输入 第一行一个整数 N,表示星星的数目: 接下来 N 行给出每颗星星的坐标,坐标用 ...