前面一章介绍了字节流的使用,提到了字节流在处理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. Iris项目结构

  2. 题解 P5594 【【XR-4】模拟赛】

    P5594 [[XR-4]模拟赛] 洛谷10月月赛 II & X Round 4 Div.2前两道签到题还是很简单的,基本上是半小时内一遍过两题 看看题解,这题STL做法有用set输出size ...

  3. Thinkphp中验证码不显示解决办法

    1.页面是否存在bom头, 2.入口文件中是否有define(‘APP_DEBUG’, TRUE); //是否开启调试模式,上线时请改为false

  4. iview渲染函数

    <Table border :columns="discountColumns" :data="discountData.rows"></Ta ...

  5. JS高级---复习

    复习 面向过程和面向对象都是编程的思想, 方式不一样 面向过程: 凡事都是亲力亲为, 所有的代码都要自己写, 每一步都要很清楚, 注重的是过程 面向对象: 执行者成为指挥者, 只要找对象, 然后让对象 ...

  6. 数据查询SELECT FROM

    [1]指定查询字段数据 SELECT  id,name,job FROM    stu_info;      #指定查询id,name,job字段的信息. SELECT  name FROM    s ...

  7. Java的JAVA_HOME、Path、CLASSPATH环境变量小结,可以借助这三个的配置去理解Oracle中的那几个环境变量的配置作用

    问题:在哪里都能执行java命令,是和JAVA_HOME变量有关系呢还是path中指定的那个java路径呢?? 刚学Java的时候,很多jdk配置教程都要求设置JAVA_HOME.Path.CLASS ...

  8. Python - metaclass元类(图)

    个人总结

  9. Springmvc-crud-02错误(添加出现中文乱码)

    错误: 在进行添加页面时使用post请求,输入中文时会出现乱码 原因: post请求不支持gbk格式,使用字符编码过滤器,设置为UTF-8编码即可 注意配置请求的字符集和响应字符集 解决方案:需要放在 ...

  10. 服务器部署网站后,公网ip可以访问,域名不能访问问题(稳)

    出现问题 这几天我网站已经部署到vps上,域名也备好案,想使用域名指向我们公网ip.指完发现用域名访问不了网站,但是公网ip可以.于是看了网上资料,好像是要清除浏览器DNS缓存,我清完没用.然后发现我 ...