Java FileInputStream与FileReader的区别
在解释Java中FileInputStream和FileReader的具体区别之前,我想讲述一下Java中InputStream和Reader的根本差异,以及分别什么时候使用InputStream和Reader。实际上, InputStream和Reader都是抽象类,并不直接地从文件或者套接字(socket)中读取数据。然而,它们之间的主要差别在于:InputStream用于读取二进制数据(字节流方式,译者注),Reader用于读取文本数据(字符流方式,译者注),准确地说,Unicode字符。那么,二进制数据和文本数据的区别是什么呢?当然,所有读取的东西本质上是字节,然后需要一套字符编码方案,把字节转换成文本。Reader类使用字符编码来解码字节,并返回字符给调用者。Reader类要么使用运行Java程序平台的默认字符编码,要么使用Charset对象或者String类型的字符编码名称,如“UTF-8”。尽管它是一个最简单的概念,当读取文本文件或从套接字中读取文本数据时,很多Java开发者会因没有指定字符编码而犯错。记住,如果你没有指定正确的编码,或者你的程序没有使用的协议中已存在的字符编码,如HTML的 “Content-Type(内容类型)”、XML文件头指定的编码,你可能无法正确地读取的所有数据。一些不是默认编码呈现的字符,可能变成“?”或小方格。一旦你知道stream和reader之间的根本区别,理解FileInputStream和FileReader之间的差异就很容易了。既可以让你从文件中读取数据,然而FileInputStream用于读取二进制数据,FileReader用来读取字符数据。
Java中FileReader vs FileInputStream
由于FileReader类继承了InputStreamReader类,使用的字符编码,要么由类提供,要么是平台默认的字符编码。请记住,InputStreamReader会缓存的字符编码。创建对象后,设置字符编码将不会有任何影响。让我们来看看如何使用Java中InputStream和FileReader的例子。你可以提供任何一个文件对象或一个包含文件位置的字符串,以开始读取文件的字符数据。这类似于FileInputStream,也提供了类似的用于读取文件源的构造函数。尽管建议使用BufferedReader来读取文件数据。我把我的eclipse的file.encoding设置成了UTF-8,然后再c盘新建一个data.txt并且输入一个永字,用记事本打开另存为UTF-8编码。这个时候我们在eclipse中运行程序,可以看到data.txt的打印二进制内容是efbbbfe6b0b8(通过Notepad++的HEX-Editor插件查看data.txt文件十六进制内容可以验证这一点),说明FileInputStream没有进行任何编码转换把data.txt的二进制内容读入java变量中。我们再来看下面一行输出 feff6c38永 就会发现FileReader通过UTF-8读取文件,然后对文件进行了编码,使其转换成unicode编码存入java变量中,这样才能在java中正确使用,因为java存储在内存里的变量都是unicode编码。如果我们把data.txt另存为ANSI(GBK)编码,FileReader还是通过UTF-8读取文件,然后对文件进行了unicode编码就会出现乱码问题。如果把eclipse的file.encoding设置成了GBK再运行程序就会打印正常,如下
d3c0
6c38永
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
import java.awt.Color;import java.io.FileInputStream;import java.io.FileReader;import java.io.IOException;/** * Java程序通过字节流和字符流的方式来读取文件数据。 * 需强调FileInputStream和FileReader的关键区别在于:FileReader用于读取字符流,而FileInputStream用来读取原始字节流。 * @author Javin Paul */public class HowToReadFileInJava { public static void main(String args[]) { // 例1 – 使用FileInputStream 读取文件内容 try (FileInputStream fis = new FileInputStream("c:/data.txt")) { int data = fis.read(); while (data != -1) { System.out.print(Integer.toHexString(data)); data = fis.read(); } } catch (IOException e) { System.out.println("Failed to read binary data from File"); e.printStackTrace(); } System.out.println();
// 例2 – Java中使用FileReader 读取文件数据 try (FileReader reader = new FileReader("c:/data.txt")) { int character = reader.read(); while (character != -1) { System.out.print(Integer.toHexString(character));
System.out.print((char) character); character = reader.read(); } } catch (IOException io) { System.out.println("Failed to read character data from File"); io.printStackTrace(); } }} |
另存为UTF-8输出:
|
1
2
3
4
5
|
UTF-8 |
另存为ANSI(GBK)输出:
|
1
2
3
4
5
|
UTF-8 |

第1个例子是按字节从文件中读取数据,因此势必会非常慢。FileInputStream的read() 方法是阻塞式的,读取字节或数据块,直到无数据输入。它要么返回数据的下一个字节,当到达文件末尾时,返回-1。这意味着,我们每循环读取一个字节,将其打印为十六进制字符串。顺便说一句,将InputStream转换成字节数组是可选的。另一方面,例2是按字符读取数据。继承自FileReader的InputStreamReader 的read() 方法读取单个字符,并返回该字符,当到达流末尾时,返回-1。这就是为什么你看到例2输出的文字跟文件中的完全一样。
这就是所有关于Java中FileInputStream和FileReader之间的区别。归根结底:使用FileReader或BufferedReader从文件中读取字符或文本数据,并总是指定字符编码;使用FileInputStream从Java中文件或套接字中读取原始字节流。
Java FileInputStream与FileReader的区别的更多相关文章
- [转]Java FileInputStream与FileReader的区别
在解释Java中FileInputStream和FileReader的具体区别之前,我想讲述一下Java中InputStream和Reader的根本差异,以及分别什么时候使用InputStream和R ...
- InputStream和Reader,FileInputStream和 FileReader的区别
一.InputStream和Reader的区别 InputStream和Reader都可以用来读数据(从文件中读取数据或从Socket中读取数据),最主要的区别如下: InputStream用来读取二 ...
- java中OutputStream字节流与字符流InputStreamReader 每一种基本IO流BufferedOutputStream,FileInputStream,FileOutputStream,BufferedInputStream,BufferedReader,BufferedWriter,FileInputStream,FileReader,FileWriter,InputStr
BufferedOutputStream,FileInputStream,FileOutputStream,BufferedInputStream,BufferedReader,BufferedWri ...
- java 接口和抽象类的区别
java 接口和抽象类的区别抽象类:1.含有抽象方法的类一定为抽象类,反过来抽象类,不一定含有抽象方法:2.抽象类必须用abstract来进行定义,抽象方法也必须用abstract来进行定义:3.抽象 ...
- JDK与Java SE/EE/ME的区别
1. Java SE(Java Platform,Standard Edition). Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用 ...
- java 静态方法和实例方法的区别
转自 java 静态方法和实例方法的区别 静态方法和实例方法的区别主要体现在两个方面: 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法 ...
- java中ArrayList 、LinkList区别
转自:http://blog.csdn.net/wuchuanpingstone/article/details/6678653 个人建议:以下这篇文章,是从例子说明的方式,解释ArrayList.L ...
- java抽象类与接口的区别及用法
java抽象类与接口的区别及用法 一.抽象类里面的方法可以有实现,但是接口里面的方法确是只能声明. 二.接口是设计的结果 :抽象类是重构的结果 . 三.java不支持多重继承,所以继承抽象类只能继承一 ...
- 【转】java int与integer的区别
java int与integer的区别 int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1 ...
随机推荐
- 使用JAVA爬取网页图片
经过之前的HttpURLConnection还有各种流的结束,已经可以开始理解怎么下载网页上的一张图片了. 对各种流不理解的话,可以翻翻前面的随笔,讲得都比较详细.在此就不细讲了. 主要流程: 1.H ...
- 「小程序JAVA实战」运行微信官方demo(四)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-04/ 微信官方小程序的demo 介绍 https://mp.weixin.qq.com/cgi-b ...
- 【Android】Android 4.0 无法接收开机广播的问题
[Android]Android 4.0 无法接收开机广播的问题 前面的文章 Android 开机广播的使用 中 已经提到Android的开机启动,但是在Android 4.0 有时可以接收到开机 ...
- 调用DLL的2种方式
[调用DLL的2种方式] DLL在生成的时候会有dll.lib2个文件,另外包含相应的.h. 1.静态方式,通过lib来引用dll,以及引入.h. 2.只通过dll来使用,前提是知道内部的函数符号.
- Hadoop之HDFS(三)HDFS的JAVA API操作
HDFS的JAVA API操作 HDFS 在生产应用中主要是客户端的开发,其核心步骤是从 HDFS 提供的 api中构造一个 HDFS 的访问客户端对象,然后通过该客户端对象操作(增删改查)HDFS ...
- 基于rank的优化
------------------siwuxie095 基于 rank 的优化 基于 size 的优化,在大多数情况下 ...
- Centos里没有lsb_release
查看Centos操作系统版本,输入指令 lsb_release -a 报无此命令 解决办法,安装lsb_release 1.执行指令:yum install -y redhat-lsb 2.安装完毕后 ...
- SqlServer—大话函数依赖与范式
说明:数据库中的某些概念真的很让人头疼,概念的东西本来就是很枯燥的,再加上枯燥的学习,那就更加枯燥了.概念这东西,你不理解也能生产东西,经验多了就行,但是为了更深入的学习,你还必须理解.这里,我抛开书 ...
- sql注意事项积累
1.一定要记住,SQL 对大小写不敏感! 2.sql中的单引号 '',如果单引号中是字符串,代表是常量 如,select 'b.phoneNumeber' from test; 如果是数字,如'123 ...
- readfile()
readfile()将一个文件写入到输出缓存参数1:文件名