深刻理解JAVA I/O系列三:字符流详解

深刻理解JAVA I/O系列三:字符流详解

字符流为什么存在

既然字节流提供了可以处理任何类型的输入/输出操做的功能,那为何还要存在字符流呢?容我慢慢道来,字节流不能直接操做Unicode字符,由于一个字符有两个字节,字节流一次只能操做一个字节。若是JAVA不能直接操做字符,我会感到JAVA对这个世界满满的恶意,因此提供对直接的字符输入/输出的支持是颇有必要的,由于咱们的口号是:一次编写,处处运行。html

字符流的概念

输出字符流:把要写入文件的字符序列(实际是unicode码元序列)转为指定编码方式下的字节序列,而后在写入文件中。java

输入字符流:把要读取的字节序列按照指定编码方式转为相应的字符序列(实际是unicode码元序列),从而写入内存中。编码

字符流的层次关系

字符流层次结构的顶层是Reader和Writer抽象类,与字节流中的InputStream、OutputStream相对应。spa

 

 下面实现这样一个功能:将字符串写入一个文件,而后再从文件中读取在控制台打印,经过这个DEMO来熟悉字符流家族中的一些经常使用流。code

首先将字符串写入文件:视频

复制代码
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();
    }
复制代码

执行结果: htm

再从文件中读取打印在控制台blog

复制代码
1         FileOutputStream fos = new FileOutputStream("d:/data.txt");
 2         OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
 3         BufferedWriter bw = new BufferedWriter(osw);
 4         String str1 = "中国移动阅读基地";
 5         String str2 = "中国移动视频基地";
 6         bw.write(str1);
 7         bw.write("\r\n");
 8         bw.write(str2);
 9         
10         bw.close();
11         
12         FileInputStream fis = new FileInputStream("d:/data.txt");
13         InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
14         BufferedReader br = new BufferedReader(isr);
15         String str;
16         while(null != (str = br.readLine()))
17         {
18             System.out.println(str);
19         }
20         br.close();
21
复制代码

执行结果:内存

中国移动阅读基地
中国移动视频基地

一、这里面的BufferedWriter、BufferedReader与字节流中的BufferedInputStream、BufferedOutputStream相对应,功能原理相似,不作展开介绍。utf-8

二、第2行、第13行代码的做用分别是将字节输出流、字节输入流经过制定的编码方式,转换成了字符输出流、字符输入流。

OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");

OutputStreamWriter、InputStreamReader就是输入/输出体系中提供的两个转换流,用于实现将字节流转换成字符流。

你们能够思考这样一个问题:为何没有把字符流转换成字节流的转换流呢?

首先想一字节流和字符流的区别:字节流比字符流的使用范围更广,但字符流比字节流操做方便。若是一个流已是字符流,也就意味着这是一个使用起来更方便的流,为何还要转换成字节流呢?反之,若是如今有一个字节流,但能够肯定这个字节流的内容都是文本内容,咱们就能够将它转换成字符流处理起来会更方便一点。因此,java只提供了字节流到字符流的转换,没有提供字符流到字节流的转换。

 

上面的DEMO是经过字节到字符的转换流来实现的,下面咱们来看看是否能够经过直接读取文本中的字符来实现:

复制代码
1 public static void main(String[] args) throws IOException
 2     {
 3         FileWriter fw = new FileWriter("d:data.txt");
 4         BufferedWriter bw = new BufferedWriter(fw);
 5         String str1 = "中国移动阅读基地";
 6         String str2 = "中国移动视频基地";
 7         bw.write(str1);
 8         bw.write("\r\n");
 9         bw.write(str2);
10         bw.close();
11         
12         FileReader fr = new FileReader("d:data.txt");
13         BufferedReader br = new BufferedReader(fr);
14         String str;
15         while(null != (str = br.readLine()))
16         {
17             System.out.println(str);
18         }
19         br.close();
20         
21     }
复制代码

执行结果:

中国移动阅读基地
中国移动视频基地

咱们能够看到,这里能够经过FileWriter/FileReader来直接操做文本文件。

一、使用FileReader或BufferedReader从文件中读取字符或文本数据,并老是指定字符编码;使用FileInputStream从Java中文件或套接字中读取原始字节流。

二、因为BufferedReader具备一个readLine方法,能够很是方便地一次读入一行内容,因此常常把读取文件内容的输入流包装成BufferedReader,用来方便地读取输入流的文本内容。

知识点TIPS

计算机的文件常被分红文本文件和二进制文件两大类:

一、咱们不妨能够这样绝对的认为:全部能用记事本打开而且看到其中字符内容文件称为文本文件,反之则是二进制文件。

二、其实计算机中全部的文件都是二进制文件,文本文只是二进制文件中的一个特殊的存在。若是二进制文件的内容刚好能被正常解析成字符时,则该二进制文件就能够称之为文本文件。

三、在有些状况下,文本文件使用了错误的字符集打开,也会生成乱码。因此若是向正常使用文本文件,必须在打开文件时使用与保存文件是相同的字符集。

相关文章
相关标签/搜索