转自:http://hi.baidu.com/danghj/item/0ef2e2c4ab95af7489ad9e39

参考资料:
  《 core java 》 12 章

使用 Java 操作文本文件的方法详解   http://java.ccidnet.com/art/3737/20041108/523627_1.html

FileReader 是什么类?和 FileInputStream 有什么不同?   http://book.hackbase.com/ask2/ask107572.htm


====================================================


自己的整理和领会:

引言:
    
  C语言只需要一个File*就可以了,与C不同,java有一系列流类型,其数量超过60种。类库的设计者声称:“有足够的理由为用户提供丰富的流类型的选择:这样做可以减少程序的错误。”例如,在C语言种,许多人认为“将输出流写入一个只读模式的文件”是很常见的错误。(事实上,这并不常见。)

我们认为在C++语言中,流接口设计者避免程序出错的主要“工具”是小心谨慎的态度,在java语言中更是如此。流库的高度复杂性迫使程序设计人员谨小慎微。

1.   File类
  
1.1 File 类介绍(《 core java 》 638 页)

File 类封装了对用户机器的文件系统进行操作的功能。

例如,可以用 File 类获得文件上次修改的时间移动,或者对文件进行删除、重命名。换句话说,流类关注的是文件内容,而 File 类关注的是文件在磁盘上的存储。

File 类的主要方法有: getName(),  getCanonicalFile(),  lastModified(),  isDerector(),  isFile(),getPath()等;

1.2 File 类与 FileInputStream 类的区别:

流类关注的是文件内容,而 File 类关注的是文件在磁盘上的存储。

File 不属于文件流 , 只能代表一个文件或是目录的路径名而已。

提示:(《 core java 》 639 页)

如果处理文件或者目录名,就应该使用 File 对象,而不是字符串。例如, File 类的 equals 方法知道一些文件系统对大小写是敏感的,目录尾的“ / ”字符无关紧要。

自己的领会:

FileInputStream 类或者 FileReader 类的构造函数有多个,其中典型的两个分别为:

一个使用 File 对象为参数;而另一个使用表示路径的 String 对象作为参数;

自己以前一直觉得直接用了 String 指定路径就可以了,一直不明白为什么很多人都先构造一个 File 对象,现在终于明白了,“如果处理文件或者目录名,就应该使用 File 对象,而不是字符串。”!

2. FileInputStream 类

2.1 FileInputStream 类介绍:

以字节为单位(非 unicode )的流处理。字节序列即:二进制数据。与编码无关,不存在乱码问题。

FileInputStream 类的主要方法有:

Read(), read( byte[] b), read( byte[],int off,int len) ,available();

2.2 FileInputStream 类与 FileReader 类的区别:

两个类的构造函数的形式和参数都是相同的,参数为 File 对象或者表示路径的 String ,它们到底有何区别呢?

l          Readers and Writers work only on line based character data, so plain text files.For anything else, you MUST use Streams.

l          JDK5 API:

FileInputStream is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader.

FileReader is meant for reading streams of characters. For reading streams of raw bytes, consider using a FileInputStream .

  

  FileInputStream :以字节流方式读取;

  FileReader :把文件转换为字符流读入;

  InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。

  用Reader读取出来的是char数组或者String ,使用InputStream读取出来的是byte数组。

  Reader类及其子类提供的字符流的读取char(16位,unicode编码),inputStream及其子类提供字节流的读取byte(8位),

  所以FileReader类是将文件按字符流的方式读取,FileInputStream则按字节流的方式读取文件;InputStreamReader可以将读如stream转换成字符流方式,是reader和stream之间的桥梁

  最初Java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类。

  FileInputStream 类以二进制输入 / 输出, I/O 速度快且效率高,但是它的 read( )方法读到的是一个字节(二进制数据),很不利于人们阅读。

  而 FileReader 类弥补了这个缺陷,可以以文本格式输入 / 输出,非常方便;比如可以使用

    while((ch = filereader.read())!=-1 )     循环来读取文件;可以使用

    BufferedReader 的 readLine() 方法一行一行的读取文本。

当我们读写文本文件的时候,采用 Reader 是非常方便的,比如 FileReader, InputStreamReader 和 BufferedReader 。其中最重要的类是InputStreamReader ,它是字节转换为字符的桥梁。 你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如 GBK 等。

  FileReader 与 InputStreamReader 涉及编码转换 ( 指定编码方式或者采用 os 默认编码 ) ,可能在不同的平台上出现乱码现象!而 FileInputStream 以二进制方式处理,不会出现乱码现象 .

2.3 自己的领会:

  如果处理纯文本文件,建议使用 FileReader ,因为更方便,也更适合阅读;但是要注意编码问题!

  其他情况(处理非纯文本文件),FileInputStream是唯一的选择;FileInputStream是进Socket通讯时会用到很多,如将文件流是Stream的方式传向服务器!

3.  FileReader 类

3.1    FileReader 类介绍:

InputStreamReader 类的子类,所有方法( read ()等)都从父类 InputStreamReader 中继承而来;

3.2 与 InputStreamReader 类的区别:

自己的领会:

该类与它的父类 InputStreamReader 的主要不同在于构造函数,主要区别也就在于构造函数!

从InputStreamReader 的构造函数中看到,参数为 InputStream 和编码方式,可以看出,当要指定编码方式时,必须使用 InputStreamReader 类;

而 FileReader 构造函数的参数与 FileInputStream 同,为 File 对象或表示 path 的 String ,可以看出,当要根据 File 对象或者 String 读取一个文件时,用 FileReader ;我想 FileReader 子类的作用也就在于这个小分工吧。

3.3   一般用法:

FileReader fr = new FileReader("ming.txt");
char[] buffer = new char[1024];
int ch = 0;
while((ch = fr.read())!=-1 ){
System.out.print((char)ch);
}

4.        InputStreamReader 类

  以文本格式输入 / 输出,可以指定编码格式;

  主要方法:  getEncoding (),read();

  一般用法:

InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"));
while((ch = isr.read())!=-1){
  System.out.print((char)ch);
}

5.        BufferedReader 类

  

Jdk5 api :

Read text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

BufferedReader 由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,

读取分行文本很适合,BufferedReader是针对Reader的,不直接针对文件,也不是只针对文件读取。

一般用法:

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ming.txt")));
String data = null;
while((data = br.readLine())!=null){
  System.out.println(data);
}

6.        总结以上内容,得出比较好的规范用法:

1)    File file = new File ("hello.txt");
    FileInputStream in=new FileInputStream(file);
2)    File file = new File ("hello.txt");
 FileInputStream in=new FileInputStream(file);
    InputStreamReader inReader=new InputStreamReader(in);
    BufferedReader bufReader=new BufferedReader(inReader);
3)    File file = new File ("hello.txt");
    FileReader fileReader=new FileReader(file);
    BufferedReader bufReader=new BufferedReader(fileReader);

7.一些写法的区别:

1)
File file = new File ("hello.txt");
FileInputStream in=new FileInputStream(file);
InputStreamReader inReader=new InputStreamReader(in);
BufferedReader bufReader=new BufferedReader(inReader);
2)
FileInputStream in=null;
File file = new File ("hello.txt");
in=new FileInputStream(file);
BufferedReader bufReader=new BufferedReader(new InputStreamReader(in));
3)
File file = new File ("hello.txt");
BufferedReader bufReader=new BufferedReader(new InputStreamReader(new FileInputStream(file)));

上述两种写法的微小区别:
a)第二种方式中把“FileInputStream in=null;”定义单独放在开始处,说明下面应该还有要用到in对象变量的地方;(BufferedReader处用了)

b)第二种方式没有定义InputStreamReader的对象变量,直接在BufferedReader的构造函数中new一个,
这种方式与第一种方式的主要区别:InputStreamReader对象只使用一次!

这对于在这里只需要使用一次这个InputStreamReader对象的应用来说更好;无需定义InputStreamReader的对象变量,接收由 new返回的该对象的引用,因为下面的程序中不需要这个InputStreamReader的对象变量,所以无需定义;所以这种情况下,第二种方式比第一 种更好一些。

c)第三种方式中,典型的三层嵌套委派关系,清晰看出Reader的委派模式(《corejava》12章有图描述该委派关系),FileInputStream和InputStreamReader都没有定义变量,new生成的对象都只是使用一次。

d)三种方式的区别也就在于FileInputStream和InputStreamReader对象是否都只使用一次,是否需要定义它们的对象变量,以及个人的编码习惯。

e但是要注意异常处理,FileInputStream(file)会抛出NotFileFoundException,

如果采用surround方式(try&catch)处理,应该用第二种方式,这样可以用System.out.println提示文件未找到;

当然在函数名后使用throws Exception,然后用第三种方式也行,但似乎这适合有用户界面的情况,把异常抛出在客户端在处理。

Java笔记--File,FileInputStream,FileReader,InputStreamReader,BufferedReader 的使用和区别的更多相关文章

  1. File,FileInputStream,FileReader,InputStreamReader,BufferedReader 的使用和区别

    1 ) File 类介绍 File 类封装了对用户机器的文件系统进行操作的功能.例如,可以用 File 类获得文件上次修改的时间移动, 或者对文件进行删除.重命名.换句话说,流类关注的是文件内容,而 ...

  2. Java读取文件-BufferedReader/FileReader/InputStreamReader/FileInputStream的关系和区别

    一.Java读取和存储文件数据流 Java读取文件,实际是将文件中的字节流转换成字符流输出到屏幕的过程   这里面涉及到两个类:InputStreamReader和OutputStreamWriter ...

  3. (转)Java 之 FileReader FileInputStream InputStreamReader BufferedReader 作用与区别

    Java 之 FileReader FileInputStream InputStreamReader BufferedReader 作用与区别 ava.io下面有两个抽象类:InputStream和 ...

  4. Java学习笔记——File类之文件管理和读写操作、下载图片

    Java学习笔记——File类之文件管理和读写操作.下载图片 File类的总结: 1.文件和文件夹的创建 2.文件的读取 3.文件的写入 4.文件的复制(字符流.字节流.处理流) 5.以图片地址下载图 ...

  5. Java学习笔记-File

    //文件操作 //2015年4月30日15:40:21 package com.alfredsun.first.main; import java.io.File; import java.io.IO ...

  6. Java学习笔记——File类文件管理及IO读写、复制操作

    File类的总结: 1.文件和文件夹的创建 2.文件的读取 3.文件的写入 4.文件的复制(字符流.字节流.处理流) 5.以图片地址下载图片 文件和文件夹 相关函数  (boolean) mkdir( ...

  7. java IO操作:FileInputStream,FileOutputStream,FileReader,FileWriter实例

    FileInputStream <span style="font-family:Verdana;">import java.io.File; import java. ...

  8. java中File IO流的笔记

    1.File文件的属性和操作 boolean exists( )  判断文件或目录是否存在boolean isFile( )  判断是否是文件boolean isDirectory( ) 判断是否是目 ...

  9. Java学习笔记-File类的基本方法

    要渐渐养成写博客的习惯-----> 前段时间看Mars的java中的I/O流没怎么懂,发现I/O流好难啊.今天重新看一遍其他教学,还有书籍,做些笔记,记录下每天的学习生活. File类的一些方法 ...

随机推荐

  1. 手动替换GCC版本

    当我们的系统里面会有2个以上版本的gcc时,系统会缺省的默认一个gcc版本,当然我们可以更改系统的默认配置,来降低gcc.g++的版本以满足不同的需求. 1.查看GCC的版本信息 $ls /usr/b ...

  2. jquery幻灯片--渐变

    网站上为了设计,需要一些幻灯片效果,现在网站有很多插件可以使用. 想要成为以为牛逼的程序员,绝对不允许只会用别人的插件而已,不然你只能是“代码”的搬运工,而不敢做出自己的创新. 首先使用jquery做 ...

  3. Commons Beanutils使用setProperty() - 就是爱Java

    有时不能只依靠getter/setter操作bean,如:需要名字动态取得的,或是访问bean内的field,甚至是集合或数组内bean的field,利用反射机制对bean的field进行处理,这时候 ...

  4. Itext 中的文本信息绝对定位

    PdfContentByte pcb = pw.getDirectContent(); pcb.beginText(); pcb.setFontAndSize(bfChinese, 12); pcb. ...

  5. 自制单片机之十二……AT89C2051烧写器的制做与调试

    现在都用S52了,还用C2051干嘛!价格也差不多.但是C2051的体积要比S51.S52小很多,而且引脚只有20只,在一些简单的控制中,这些引脚已足够了,小的体积更具有优势些.但目前好像还没有支持在 ...

  6. Qt浅谈之二十七进程间通信之QtDBus

    一.简介 DBus的出现,使得Linux进程间通信更加便捷,不仅可以和用户空间应用程序进行通信,而且还可以和内核的程序进行通信,DBus使得Linux变得更加智能,更加具有交互性.        DB ...

  7. ImageMagick提取图像原始数据(ImageData/RawData)

    我用的是ImageMagickWand的接口,因为这接口比Core接口更上层,所以官方文档推荐用. 抽取整个图像文件字节数据: http://www.imagemagick.org/discourse ...

  8. to_char函数引发的不走索引

    SQL> conn cowork_czsh/cowork_czsh Connected. SQL> set linesize 200 SQL> set pagesize 200 SQ ...

  9. android使用BlueStacks作为模拟器

    android原生的模拟器启动比较慢,偶尔还会出现一些莫名的问题,我们除了可以使用我们的android手机来进行调试外,还可以使用第三方的android模拟器,例如BlueStacks模拟器: 相对原 ...

  10. 批量更新sql |批量update sql

    图所示现需要批量更新table2表内字段Pwd更新userName对IP地址username与Ip对应关系table1所示 update table2 set pwd=table1.ip from t ...