字符流为何存在

既然字节流提供了能够处理任何类型的输入/输出操作的功能,那为什么还要存在字符流呢?容我慢慢道来,字节流不能直接操作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、在有些情况下,文本文件使用了错误的字符集打开,也会生成乱码。所以如果向正常使用文本文件,必须在打开文件时使用与保存文件是相同的字符集。

最新文章

  1. day7
  2. WebService 用法
  3. (译)如何在ASP.NET中安全使用ViewState
  4. A Tour of Go Interfaces are satisfied implicitly
  5. MFC常用控件CListCtrl 、CSliderCtrl、CToolTipCtrl、CTreeCtrl的自绘
  6. Windows server 2008搭建php运行环境
  7. 原生js二级联动
  8. Java面向对象 继承(上)
  9. VS2010每次调试都出现“此项目已经过期”提示
  10. [转]Docker版本变化和新版安装
  11. my live health
  12. impala系列: 时间函数
  13. 《一头扎进SpringMvc视频教程》
  14. Mac 终端Terminal光标移动快捷键
  15. PHP运行出现Notice : Use of undefined constant 的解决办法
  16. Fragment的详细使用
  17. HTTP协议之认证
  18. Ruby require, load include 区别
  19. 20170708xlVBA添加新产品修改公式
  20. failed creating java jvm.dll

热门文章

  1. GoLand(一)安装
  2. 20145207《Java程序设计》实验四( Android程序设计)实验报告
  3. hashMap put的返回值测试
  4. JavaWeb总结(五)
  5. PostgreSQL集群方案相关索引页
  6. P2939 [USACO09FEB]改造路Revamping Trails
  7. 【Java字符序列】Pattern
  8. 【PaPaPa】集成B/S主流技术的MVC5项目 - 实干派:说做就做,我们已经起航,你还在观望吗
  9. 用Metaclass实现一个精简的ORM框架
  10. REVIT个人学习笔记——1.简介及熟悉界面