深入理解JAVA I/O系列三:字符流详解
字符流为何存在
既然字节流提供了能够处理任何类型的输入/输出操作的功能,那为什么还要存在字符流呢?容我慢慢道来,字节流不能直接操作Unicode字符,因为一个字符有两个字节,字节流一次只能操作一个字节。如果JAVA不能直接操作字符,我会感到JAVA对这个世界满满的恶意,所以提供对直接的字符输入/输出的支持是很有必要的,因为我们的口号是:一次编写,到处运行。
字符流的概念
输出字符流:把要写入文件的字符序列(实际是unicode码元序列)转为指定编码方式下的字节序列,然后在写入文件中。
输入字符流:把要读取的字节序列按照指定编码方式转为相应的字符序列(实际是unicode码元序列),从而写入内存中。
字符流的层次关系
字符流层次结构的顶层是Reader和Writer抽象类,与字节流中的InputStream、OutputStream相对应。
下面实现这样一个功能:将字符串写入一个文件,然后再从文件中读取在控制台打印,通过这个DEMO来熟悉字符流家族中的一些常用流。
首先将字符串写入文件:
public static void main(String[] args) throws IOException
{
FileOutputStream fis = new FileOutputStream("d:/data.txt");
OutputStreamWriter osw = new OutputStreamWriter(fis);
BufferedWriter bw = new BufferedWriter(osw);
String str1 = "中国移动阅读基地";
String str2 = "中国移动视频基地";
bw.write(str1);
bw.write("\r\n");
bw.write(str2); bw.close();
}
执行结果:
再从文件中读取打印在控制台
FileOutputStream fos = new FileOutputStream("d:/data.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
BufferedWriter bw = new BufferedWriter(osw);
String str1 = "中国移动阅读基地";
String str2 = "中国移动视频基地";
bw.write(str1);
bw.write("\r\n");
bw.write(str2); bw.close(); FileInputStream fis = new FileInputStream("d:/data.txt");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String str;
while(null != (str = br.readLine()))
{
System.out.println(str);
}
br.close();
执行结果:
中国移动阅读基地
中国移动视频基地
1、这里面的BufferedWriter、BufferedReader与字节流中的BufferedInputStream、BufferedOutputStream相对应,功能原理类似,不做展开介绍。
2、第2行、第13行代码的作用分别是将字节输出流、字节输入流通过制定的编码方式,转换成了字符输出流、字符输入流。
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
OutputStreamWriter、InputStreamReader就是输入/输出体系中提供的两个转换流,用于实现将字节流转换成字符流。
大家可以思考这样一个问题:为什么没有把字符流转换成字节流的转换流呢?
首先想一字节流和字符流的区别:字节流比字符流的使用范围更广,但字符流比字节流操作方便。如果一个流已经是字符流,也就意味着这是一个使用起来更方便的流,为什么还要转换成字节流呢?反之,如果现在有一个字节流,但可以确定这个字节流的内容都是文本内容,我们就可以将它转换成字符流处理起来会更方便一点。所以,java只提供了字节流到字符流的转换,没有提供字符流到字节流的转换。
上面的DEMO是通过字节到字符的转换流来实现的,下面我们来看看是否可以通过直接读取文本中的字符来实现:
public static void main(String[] args) throws IOException
{
FileWriter fw = new FileWriter("d:data.txt");
BufferedWriter bw = new BufferedWriter(fw);
String str1 = "中国移动阅读基地";
String str2 = "中国移动视频基地";
bw.write(str1);
bw.write("\r\n");
bw.write(str2);
bw.close(); FileReader fr = new FileReader("d:data.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while(null != (str = br.readLine()))
{
System.out.println(str);
}
br.close(); }
执行结果:
中国移动阅读基地
中国移动视频基地
我们可以看到,这里可以通过FileWriter/FileReader来直接操作文本文件。
1、使用FileReader或BufferedReader从文件中读取字符或文本数据,并总是指定字符编码;使用FileInputStream从Java中文件或套接字中读取原始字节流。
2、由于BufferedReader具有一个readLine方法,可以非常方便地一次读入一行内容,所以经常把读取文件内容的输入流包装成BufferedReader,用来方便地读取输入流的文本内容。
知识点TIPS
计算机的文件常被分成文本文件和二进制文件两大类:
1、我们不妨可以这样绝对的认为:所有能用记事本打开并且看到其中字符内容文件称为文本文件,反之则是二进制文件。
2、其实计算机中所有的文件都是二进制文件,文本文只是二进制文件中的一个特殊的存在。如果二进制文件的内容恰好能被正常解析成字符时,则该二进制文件就可以称之为文本文件。
3、在有些情况下,文本文件使用了错误的字符集打开,也会生成乱码。所以如果向正常使用文本文件,必须在打开文件时使用与保存文件是相同的字符集。
深入理解JAVA I/O系列三:字符流详解的更多相关文章
- 深入理解JAVA I/O系列二:字节流详解
流的概念 JAVA程序通过流来完成输入/输出.流是生产或消费信息的抽象,流通过JAVA的输入输出与物理设备链接,尽管与它们链接的物理设备不尽相同,所有流的行为具有相同的方式.这样就意味一个输入流能够抽 ...
- Hexo系列(三) 常用命令详解
Hexo 框架可以帮助我们快速创建一个属于自己的博客网站,熟悉 Hexo 框架提供的命令有利于我们管理博客 1.hexo init hexo init 命令用于初始化本地文件夹为网站的根目录 $ he ...
- elasticsearch系列三:索引详解(分词器、文档管理、路由详解(集群))
一.分词器 1. 认识分词器 1.1 Analyzer 分析器 在ES中一个Analyzer 由下面三种组件组合而成: character filter :字符过滤器,对文本进行字符过滤处理,如 ...
- 【Java IO流】字节流和字符流详解
字节流和字符流 对于文件必然有读和写的操作,读和写就对应了输入和输出流,流又分成字节和字符流. 1.从对文件的操作来讲,有读和写的操作——也就是输入和输出. 2.从流的流向来讲,有输入和输出之分. 3 ...
- 深入理解java虚拟机(八)类加载过程详解
类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(In ...
- PE文件学习系列三-PE头详解
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q Q:408365330 E-Mail:egojit@qq.com 最近比较忙 ...
- Java容器解析系列(10) Map AbstractMap 详解
前面介绍了List和Queue相关源码,这篇开始,我们先来学习一种java集合中的除Collection外的另一个分支------Map,这一分支的类图结构如下: 这里为什么不先介绍Set相关:因为很 ...
- Java容器解析系列(5) AbstractSequentialList LinkedList 详解
AbstractSequentialList为顺序访问的list提供了一个骨架实现,使实现顺序访问的list变得简单; 我们来看源码: /** AbstractSequentialList 继承自 A ...
- JavaIO流原理之常用字节流和字符流详解以及Buffered高效的原理
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827509.html Java的流体系十分庞大,我们来看看体系图: 这么庞大的体系里面 ...
随机推荐
- golang中的字符串拼接
go语言中支持的字符串拼接的方法有很多种,这里就来罗列一下 常用的字符串拼接方法 1.最常用的方法肯定是 + 连接两个字符串.这与python类似,不过由于golang中的字符串是不可变的类型,因此用 ...
- elastic-job+zookeeper实现分布式定时任务调度的使用(springboot版本)
总体思路,要确认一个定时任务需要一个cron表达式+jobDetail: 现在要让实现定时任务的协调,则就让zookeeper,简单说就是需要3要素,zk对象+cron+jobDetail: 总的项目 ...
- 9 ORM-高阶补充(未完成)
https://www.cnblogs.com/alice-bj/p/9195846.html#_labelTop https://www.cnblogs.com/yuanchenqi/article ...
- centos中如何添加环境变量
在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行“php -v”命令查看当前php版本信息时时, ...
- Python 从零搭建 Conf_Web 配置管理平台
作者:Eagle 某船舶行业科技公司,运维工程师,51Reboot学员.通过在51Reboot学习,由运维工程师转至运维开发工程师.完成公司自动化平台的构建,对运维开发有了自己的理解,空闲时间写了这么 ...
- 设计模式之module模式及其改进
写在前面 编写易于维护的代码,其中最重要的方面就是能够找到代码中重复出现的主题并优化他们,这也是设计模式最有价值的地方 <head first设计模式>里有一篇文章,是说使用模式的心智, ...
- Json对象与Json字符串的转化、JSON字符串与Java对象的转换(转)
一.Json对象与Json字符串的转化 1.jQuery插件支持的转换方式: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符 ...
- 树莓派3b添加python时间同步脚本
树莓派没有电池,因此断电后系统时间会停止,直到你开机后又继续计时,所以会造成系统时间和实际时间有很大的误差. 因为项目需要用到本地时间,精度要求不高不想折腾(如果需要高精度,需要安装ntp),所以考虑 ...
- Windows7 jmeter3.1安装(咋个安装?)
这是一个比较详细的安装教程0.0,不懂可以私我,有错也可以私我 1.0 首先我们得有jdk,我选择的是1.8版本的jdk, QQ群:550654190,(进群答案:李熠)群文件里有. 进去后下载 ...
- Ubuntu安装Oh My Zsh
1. 安装ZSH sudo apt-get install zsh 安装完后需要注销或重启才能生效.注销或重启后打开终端,会出现ZSH的界面,选择(2) 2. 安装Oh My Zsh sh -c &q ...