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 ...
随机推荐
- 排查 k8s 集群 master 节点无法正常工作的问题
搭建的是 k8s 高可用集群,用了 3 台 master 节点,2 台 master 节点宕机后,仅剩的 1 台无法正常工作. 运行 kubectl get nodes 命令出现下面的错误 The c ...
- robotframework初始化时有返回值怎么处理
方法一:set suite variable/set global variable 假设执行add school class会返回一个id,这个id在后面的脚本中还要使用. 因为初始化时只能有一个关 ...
- Android学习10
SharedPreferences 今天练习了利用SharedPreferences保存登录用户名密码: layout布局: <?xml version="1.0" enco ...
- Java 链接mongodb 执行集合查询
public static String mongodbConnection(String phone){ String sendCode = null; //创建mongodb链接地址 MongoC ...
- 【Python redis】
目录 基本用法 连接池 基本命令 String Hash List set "下载:pip install redis @ *** 基本用法 redis库提供两个类,Redis和Strict ...
- 计算机二级-C语言-程序填空题-190107记录
//给定程序的功能是:调用fun函数建立班级通讯录.通讯中记录每位学生的编号,姓名和电话号码.班级的人数和学生的信息从键盘读入,每个人的信息作为一个数据块(代表要使用结构体)写到名为myfile5.d ...
- python报错使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: SyntaxError: invalid syntax问题
参考链接:https://blog.csdn.net/ltz150/article/details/77870735 1.背景: CentOS 7升级Python到3.6.2后,需要在/usr/bin ...
- C#面向对象三大特性:继承
什么是继承 定义:继承是面向对象编程语言中的一个重要特性,当一个类A能够获取另一个类B中所有非私有的数据和操作的定义作为自己的部分或全部成分时,就称这两个类之间具有继承关系.被继承的类B称为父类或基类 ...
- es6二进制数组--基础
一.概念二进制数组由 ArrayBuffer对象 TypeArray 视图和DataView视图 三部分组成是javascript操作二进制数据的一个接口. 早在2011年2月就已经发布,但是由于ES ...
- opencv python:边缘保留滤波(EPF)
EPF:E边缘,P保留,F滤波 import cv2 as cv import numpy as np def bi_demo(image): # bilateralFilter(src, d, si ...