l 使用 Java 操作文本文件的方法详解
http://java.ccidnet.com/art/3737/20041108/523627_1.html
l FileReader 是什么类?和 FileInputStream 有什么不同???
http://book.hackbase.com/ask2/ask107572.htm
自己的整理和领会:
引言:
C语言只需要一个File*就可以了,与C不同,java有一系列流类型,其数量超过60种。类库的设计者声称:“有
足够的理由为用户提供丰富的流类型的选择:这样做可以减少程序的错误。”例如,在C语言种,许多人认为“
将输出流写入一个只读模式的文件”是很常见的错误。(事实上,这并不常见。)
我们认为在C++语言中,流接口设计者避免程序出错的主要“工具”是小心谨慎的态度,在java语言中更是如
此。流库的高度复杂性迫使程序设计人员谨小慎微。
1. File类
1 ) File 类介绍(《 core java 》 638 页)
File 类封装了对用户机器的文件系统进行操作的功能。例如,可以用 File 类获得文件上次修改的时间移动,
或者对文件进行删除、重命名。换句话说,流类关注的是文件内容,而 File 类关注的是文件在磁盘上的存储
。
File 类的主要方法有: getName(),getCanonicalFile(),lastModified(),isDerector(),isFile(),getPath()
等;
2 ) File 类与 FileInputStream 类的区别:
流类关注的是文件内容,而 File 类关注的是文件在磁盘上的存储。
File 不属于文件流 , 只能代表一个文件或是目录的路径名而已。
提示:(《 core java 》 639 页)
如果处理文件或者目录名,就应该使用 File 对象,而不是字符串。例如, File 类的 equals 方法知道一些
文件系统对大小写是敏感的,目录尾的“ / ”字符无关紧要。
自己的领会:
FileInputStream 类或者 FileReader 类的构造函数有多个,其中典型的两个分别为:一个使用 File 对象为
参数;而另一个使用表示路径的 String 对象作为参数;自己以前一直觉得直接用了 String 指定路径就可以
了,一直不明白为什么很多人都先构造一个 File 对象,现在终于明白了,“如果处理文件或者目录名,就应
该使用 File 对象,而不是字符串。”!
2. FileInputStream 类
1 ) FileInputStream 类介绍:
以字节为单位(非 unicode )的流处理。字节序列即:二进制数据。与编码无关,不存在乱码问题。
FileInputStream 类的主要方法有:
Read (), read ( byte[] b ), read ( byte[],int off,int len ) ,available();
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 .
l FileInputStream :以字节流方式读取; FileReader :把文件转换为字符流读入;
l InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。用Reader读取出
来的是char数组或者String ,使用InputStream读取出来的是byte数组。
l Reader类及其子类提供的字符流的读取char(16位,unicode编码),inputStream及其子类提供字节
流的读取byte(8位),所以FileReader类是将文件按字符流的方式读取,FileInputStream则按字节流的方式
读取文件;InputStreamReader可以将读如stream转换成字符流方式,是reader和stream之间的桥梁
l 最初Java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类。
l FileInputStream 类以二进制输入 / 输出, I/O 速度快且效率搞,但是它的 read ()方法读到
的是一个字节(二进制数据),很不利于人们阅读。
l 而 FileReader 类弥补了这个缺陷,可以以文本格式输入 / 输出,非常方便;比如可以使用
while((ch = filereader.read())!=-1 ) 循环来读取文件;可以使用 BufferedReader 的 readLine() 方法一
行一行的读取文本。
l 当我们读写文本文件的时候,采用 Reader 是非常方便的,比如 FileReader ,
InputStreamReader 和 BufferedReader 。其中最重要的类是 InputStreamReader ,它是字节转换为字符的桥
梁。 你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如 GBK 等
。
l FileReader 与 InputStreamReader 涉及编码转换 ( 指定编码方式或者采用 os 默认编码 ) ,可
能在不同的平台上出现乱码现象!而 FileInputStream 以二进制方式处理,不会出现乱码现象 .
3 )自己的领会:
l 如果处理纯文本文件,建议使用 FileReader ,因为更方便,也更适合阅读;但是要注意编码问题
!
l 其他情况(处理非纯文本文件),FileInputStream是唯一的选择;FileInputStream是进Socket通讯时会
用到很多,如将文件流是Stream的方式传向服务器!
3. FileReader 类
1) FileReader 类介绍:
InputStreamReader 类的子类,所有方法( read ()等)都从父类 InputStreamReader 中继承而来;
2) 与 InputStreamReader 类的区别:
l 自己的领会:
该类与它的父类 InputStreamReader 的主要不同在于构造函数,主要区别也就在于构造函数!从
InputStreamReader 的构造函数中看到,参数为 InputStream 和编码方式,可以看出,当要指定编码方式时,
必须使用 InputStreamReader 类;而 FileReader 构造函数的参数与 FileInputStream 同,为 File 对象或
表示 path 的 String ,可以看出,当要根据 File 对象或者 String 读取一个文件时,用 FileReader ;我
想 FileReader 子类的作用也就在于这个小分工吧。
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 类
l 以文本格式输入 / 输出,可以指定编码格式;
l 主要方法:
getEncoding (),read();
l 一般用法:
InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"));
while((ch = isr.read())!=-1)
{
System.out.print((char)ch);
}
5. BufferedReader 类
l Jdk5 api :
Read text from a character-input stream, buffering characters so as to provide for the efficient
reading of characters, arrays, and lines.
l BufferedReader 由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,
读取分行文本很适合,BufferedReader是针对Reader的,不直接针对文件,也不是只针对文件读取。
l 一般用法:
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操作文本文件
最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类,这两个类都是抽象类,Writer中write(char[] ch,int off,int length),flush()和close()方法为抽象方法,Reader中read(char[] ch,int off,int length)和close()方法是抽象方法。子类应该分别实现他们。
当我们读写文本文件的时候,采用Reader是非常方便的,比如FileReader,InputStreamReader和BufferedReader。其中最重要的类是InputStreamReader,它是字节转换为字符的桥梁。你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。当使用FileReader读取文件的时候。
FileReader fr = new FileReader("ming.txt");
int ch = 0;
while((ch = fr.read())!=-1 )
{
System.out.print((char)ch);
}
其中read()方法返回的是读取得下个字符。当然你也可以使用read(char[] ch,int off,int length)这和处理二进制文件的时候类似,不多说了。如果使用InputStreamReader来读取文件的时候
while((ch = isr.read())!=-1)
{
System.out.print((char)ch);
}
这和FileReader并没有什么区别,事实上在FileReader中的方法都是从InputStreamReader中继承过来的。read()方法是比较好费时间的,如果为了提高效率我们可以使用BufferedReader对Reader进行包装,这样可以提高读取得速度,我们可以一行一行的读取文本,使用readLine()方法。
BufferedReader br = new BufferedReader(new InputStreamReader(newFileInputStream("ming.txt")));
String data = null;
while((data = br.readLine())!=null)
{
System.out.println(data);
}
当你明白了如何用Reader来读取文本文件的时候那么用Writer写文件同样非常简单。有一点需要注意,当你写文件的时候,为了提高效率,写入的数据会先放入缓冲区,然后写入文件。因此有时候你需要主动调用flush()方法。与上面对应的写文件的方法为
FileWriter fw = new FileWriter("hello.txt");
String s = "hello world";
fw.write(s,0,s.length());
fw.flush();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("hello2.txt"));
osw.write(s,0,s.length());
osw.flush();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("hello3.txt")),true);
pw.println(s);
不要忘记用完后关闭流!下面是个小例子,帮助新手理解。其实有的时候java的IO系统是需要我们多记记的,不然哪天就生疏了。测试文件的内容为
ming.txt
hello world i like java language
import java.io.*;
public class TestFile2
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("ming.txt");
char[] buffer = new char[1024];
int ch = 0;
while((ch = fr.read())!=-1 )
{
System.out.print((char)ch);
}
InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"));
while((ch = isr.read())!=-1)
{
System.out.print((char)ch);
}
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ming.txt")));
String data = null;
while((data = br.readLine())!=null)
{
System.out.println(data);
}
FileWriter fw = new FileWriter("hello.txt");
String s = "hello world";
fw.write(s,0,s.length());
fw.flush();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("hello2.txt"));
osw.write(s,0,s.length());
osw.flush();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("hello3.txt")),true);
pw.println(s);
fr.close();
isr.close();
br.close();
fw.close();
osw.close();
pw.close();
}
}
|
相关推荐
【Java.SE.Lesson.4_code.rar】这个压缩包文件包含了北京圣思园Java培训课程的第四课时的源代码,主要关注的是Java Standard Edition(Java SE)的相关编程知识。Java SE是Java平台的核心,用于开发和运行桌面应用...
【Java.SE.Lesson.5_code.rar】这个压缩包文件显然包含了北京圣思园Java培训课程中的第五课时的源代码。这通常意味着我们将深入到Java编程语言的核心概念中,特别是那些在Java Standard Edition(Java SE)环境下的...
Java SE 8是Java平台标准版的第八个主要版本,它引入了多项重要的新特性,如lambda表达式、函数式编程接口、Stream API以及日期与时间API的改进。这些新特性极大地提高了代码的简洁性和执行效率,使得Java在处理并发...
javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing....
javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing.border ...
对于初学者来说,了解并掌握Java SE的基础知识是成为Java程序员的第一步。下面将详细介绍标题和描述中提及的一些关键知识点。 1. **Hello World**:这是所有编程语言入门的经典示例,用于验证环境配置是否正确。在...
2. **第三章 Java基础语法**:涵盖了变量、数据类型、常量、运算符、流程控制语句(如if-else,for,while)等内容。基础语法是任何编程语言的基石,理解它们能够帮助初学者编写简单的程序。 3. **第五章 数组**:...
javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing.border ...
### Java SE 基础知识点梳理 #### 一、字符串(String) **1. 字符串定义** 在 Java 中,`String` 类是最常用的字符串表示方式。`String` 类是不可变的,这意味着一旦创建了一个 `String` 对象,它的值就不能被改变...
【SE_JAVA_EXP_E046.zip】是一个与Java编程相关的学习资源,它包含了易智教云课堂上一道练习题的满分答案。这道习题可能是面向正在学习Java编程的学生们,旨在帮助他们理解和掌握Java语言的核心概念和编程技巧。由于...
《Java SE Tutorial 2022-03-04》是针对Java Standard Edition的一份详细教程,旨在帮助开发者深入理解和掌握Java编程语言的核心概念和技术。这份教程可能包含了从基础到高级的各个层面,旨在让学习者能够全面了解并...
javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing.border ...
### 第三章:面向对象程序开发 - **封装**:隐藏对象的实现细节。 - **继承**:子类继承父类的属性和方法。 - **多态**:同一接口的不同实现。 ### 第四章:异常机制 - **异常处理**:使用try-catch-finally结构...
Java-SE 罗召勇的PDF教程是一个适合初学者的Java Standard Edition(Java SE)学习资源,它包含了多个章节,旨在帮助用户从基础开始掌握Java编程语言。本教程覆盖了从Java的基础语法到更高级的概念,通过例题和代码...
javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing....
在"VIP09_JavaSE_JavaIO_File_day0307-1.rar"这个压缩包中,我们可以预想它包含的是一个关于Java IO和File类的课程或教程的第三天第七节的内容。下面,我们将深入探讨Java IO和File类的相关知识点。 1. **Java IO...
JAVA-SE入门学习——第九讲IO流 在 Java 中,IO 流(Input/Output Stream)是一种基本的输入/输出机制,它允许程序读取和写入各种类型的数据。IO 流是 Java 编程语言的核心组件之一,它提供了一种通用的方式来处理...
4. **IO流**:Java的IO流系统用于读写文件、网络通信等操作。它分为字节流和字符流两大类,有输入流和输出流之分,并且支持双向流和过滤流。熟悉InputStream、OutputStream、Reader、Writer及其子类,能有效进行数据...
javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing....
Java SE Development Kit(JDK)8u144是Oracle公司发布的Java Standard Edition开发工具包的一个更新版本,主要用于Java应用程序的开发和运行。这个版本包含了Java编译器、Java运行时环境、Java类库以及相关的开发...