使用Reader与Writer流类
InputStream和OutputStream类通常是用处理“字节流”即“位流”的,也就是说二进制文件,而Reader与Writerl类则是用来处理“字符流”的,也就是文本文件。与字节输入流的功能一样,字符输入流类Reader与Writer只是建立一条通往文本文件的通道,而要实现对字符数据的读写操作,还需要相应读、写方法来完成。
Reader类常用方法:
| 常用方法 | 功能说明 |
|---|---|
| public int read() | 从输入流中第一个字符 |
| public inr read(char[] cbuf) | 从输入流中读最多cbuf.length个字符,存入字符数组cbuf中 |
| public inr read(char[] cbuffer,int off,int len) | 从输入流中读最多len个字符,存入字符数组cbuffer中,从off开始的位置 |
| public long skip(long n) | 从输入流中最多向后跳n个字符 |
| public boolean ready() | 判断流是否做好读的准备 |
| public void mark(int readAheadLinit) | 标记输入流的当前位置 |
| public boolean markSupported() | 测试输入流是否支持mark |
| public void reset() | 重新定位输入流 |
| public void close() | 关闭输入流 |
writer类常用方法:
| 常用方法 | 功能说明 |
|---|---|
| public void write(int c) | 将单一字符c输入到流中 |
| public void write(iString str) | j将字符串str输出到流中 |
| public void write(char[] cbuf) | 将字符数组cbuf输出到流 |
| public void write(char[] cbuf,int off,int len) | 将字符数组按指定的格式输出(off表示索引,len表示写入的字符数)到流中 |
| public void flush() | 将缓存区中的数据写到文件中 |
| public void close() | 关闭输出流 |
1.FileReader类
文件字符输入流类FileReader是继承自InputStreamReader类,而InputStreamReader类又继承Reader类。
在使用FileReader类读取文件时,必须先调用FileReader()构造方法创建FileReader类的对象,在利用它调用read()方法。
FileReader类的构造方法
| 构造方法 | 功能说明 |
|---|---|
| public FileReader(String name) | 根据文件名称创建一个可读取的输入流对象 |
package jl105FileReader类读取文件;
import java.io.*;
public class jl1005 {
public static void main(String[] args)throws IOException{
char[] c=new char[500];
try(FileReader fr=new FileReader("E:/cqj/myfile2.txt");)
{
int num = fr.read(c);
//用int num=c.length会出错,显示字符个数为500
String str=new String(c,0,num);//string的构造方法
System.out.println("读取的字符个数为:"+num+",其内容如下:");
System.out.println(str);
}
/* catch(FileNotFoundException e)
{
System.out.print("系统找不到指定文件!");
}*/
}
}
预计输出:
读取的字符个数为:36,其内容如下:
我喜欢Java!因为它功能强大
安全性好
可靠性高
实际运行:
读取的字符个数为:36,其内容如下:
鎴戝枩娆ava锛佸洜涓哄畠鍔熻兘寮哄ぇ
瀹夊叏鎬уソ
鍙潬鎬ч珮

现在想一个问题,为什么会乱码呢?
乱码是因为文本所提供的编码和Java能读取的编码不同,所以产生了乱码。
然后我查阅了资料,想了解如何修改Eclipse上的默认的编码。(上述图片是UTF-8的格式)
感兴趣的小伙伴可以点击进入我查阅到的原文一起学习(侵权立删)
接下来看看如何修改,修改之后输出的原文是否正确。
首先选择你要修改编码的程序或者工程,然后点击右键,选择 Properties
我们能够看见,默认格式是GBK

然后点击Other选项,将其设置成你将要读取的文本文件格式就行

设置完之后,我们再看输出结果
��ȡ���ַ�����Ϊ��29�����������£�
我喜欢Java!因为它功能强大
安全性好
可靠性高
文本内容就完全输出出来了。
2.FileWrite类
文件字符输出流类FileWriter继承自OutputStreamWriter类,而OutputStreamWriter类又继承与Writer类。
要使用FileWriter类将数据写入文件,必须先调用FileWriter()构造方法创建FileWriter类对象,再利用它来调用write()方法。FileWriter类的构造方法见下表:
FileWriter类的构造方法:
| 构造方法 | 功能说明 |
|---|---|
| public FileWriter(String filename) | 根据所给文件名创建一个可供写入字符数据的输出流对象,原先的文件会被覆盖 |
| public FileWriter(String filename,boolean a) | 同上,但如果a设置为true,则会将数据追加在原先文件的后面 |
package jl106FileWriter类写入文件;
import java.io.*;
public class jl06 {
public static void main(String[] args)throws IOException
{
/*方法一:
FileWriter fw=new FileWriter("E:/cqj/myfile3.txt");
char c[]= {'H','e','l','l','o','\r','\n'};
String str="欢迎使用Java哦!";
fw.write(c);
fw.write(str);
fw.close();*/
//方法二:
try(FileWriter fw=new FileWriter("E:/cqj/myfile4.txt");)
{
char[]c={'H','e','l','l','o','\r','\n'};
String str="欢迎使用Java哦!!!";
fw.write(c);
fw.write(str);
}
catch(IOException e) {
}
try(FileReader fr=new FileReader("E:/cqj/myfile4.txt");)
{
char[]c=new char[500];
int num=fr.read(c);
String str=new String(c,0,num);
System.out.println("此次共读了"+num+"个字符,内容如下:");
System.out.println(str);
}
catch(IOException e) {
}
/* catch(FileNotFoundException e) {
System.out.print("文件未发现!");
}*/
}
}
方法二:运行结果:
此次共读了19个字符,内容如下:
Hello
欢迎使用Java哦!!!
方法一的运行结果

此时能输原文输出,没有改变Eclipse的设置,也不会有乱码现象,具体原因未知,欢迎大家在评论区下方指教。(个人猜测:可是系统写入是文本时自动进行了格式转换,会产生一个“标记”,然后读取时又可以通过“标记”转换回来,而手动在文本中输入时,没有那种特定的“标记”,所以造成乱码)

3.BufferedReader类
缓冲字符输入流类BufferedReader继承Reader类,BufferedReader类是用来读取缓冲区里的数据。属于BufferedReader类来读取缓冲区中的数据之前,必须先创建FileReader类对象,再以该对象为参数来创建BufferedReader类对象,然后才可以利用此对象来读取缓冲区的数据。BufferedReader类有两个构造方法,如下表:
BufferedReader类的构造方法
| 构造方法 | 功能说明 |
|---|---|
| public BufferedReader(Reader in) | 创建缓冲字符输入流 |
| public BufferedReader(Reader in,int size) | 创建缓冲区字符输入流,并设置缓冲区大小 |
BufferedReader类的常用方法
| 常用方法 | 功能说明 |
|---|---|
| public int read() | 读取单一字符 |
| public int read(char[] cbuf) | 从流中读取字符并写入到字符数组cbuf中 |
| public int read(char[] cbuf,int off,int len) | 从流中读取字符存放到字符数组cbuf中(off表示数组下标,len表示读取的字符数) |
| public long skip(long n) | 跳过n个字符数 |
| public String readLine() | 读取一行字符串 |
| public void close() | 关闭流 |
package jl107利用BufferedReader读取文件;
import java.io.*;
public class jl1007 {
public static void main(String[] args)throws IOException
{
String thisLine;
int count=0;
try(FileReader fr=new FileReader("E:/cqj/myfile5.txt");
BufferedReader bfr=new BufferedReader(fr);)
{
while((thisLine=bfr.readLine())!=null)
{
count++;
System.out.println(thisLine);
}
}
System.out.println("共读取了"+count+"行");
}
}
运行结果:
Hello
娆㈣繋浣跨敤 java!
共读取了2行
文本文件的信息是

改变编码规则纠正后:

4.BufferedWriter类
缓冲字符输出流类BufferedWriter继承Writer类,BufferedWriter类是用来将数据写出到缓存区中。使用BufferedWriter类将数据写入缓冲区的过程与使用BufferedReader类从缓冲区读出数据的过程相似。
首先必须先创建FileWriter对象,再以该对象为参数来创建BufferedWriter类的对象,然后就可以利用此对象将数据写入缓冲区中。
所不同的是,缓冲区内的数据最后必须要用flush()方法将缓冲区清空,也就是将缓冲区中的数据全部写入到文件内。BufferedWriter的构造方法如下:
BufferedWriter的构造方法
| 构造方法 | 功能说明 |
|---|---|
| public BufferedWriter(Writer out) | 创建缓冲区字符输出流 |
| public BufferedWriter(Writer out,int size) | 创建缓冲区字符输入流,并设置缓冲区大小 |
BufferedWriter的常用方法
| 常用方法 | 功能说明 |
|---|---|
| public void writer(int c) | 将单一字符c输入到流中 |
| public void write(char[] cbuf,int off,int len) | 将字符数组按指定的格式输出缓冲流中(off表示索引,len表示写入的字符数) |
| public void write(iString str,int off,int len) | 写入字符串(off表示下标,len表示写入的字符数) |
| publicvoidnewLine() | 写入回车换行符 |
| public void flush() | 将缓存区中的数据写到文件中 |
| public void close() | 关闭输出流 |
package jl108利用BufferedWriter写入文件;
import java.io.*;
public class jl108 {
public static void main(String[] args)throws IOException
{
String str=new String();
try(BufferedReader in = new BufferedReader(new FileReader("E:/cqj/myfile4.txt"));
BufferedWriter out = new BufferedWriter(new FileWriter("E:/cqj/myfile41.txt"));)
{
while((str=in.readLine())!=null)
{
System.out.println(str);
out.write(str);
out.newLine();
}
out.flush();
}
catch(IOException e) {
System.out.print("错误!"+e);
}
}
}
运行结果:
Hello
欢迎使用Java哦!!!
说明:此时的“myfile4.txt”是由程序写入的,所以运行出来的不会有乱码,如果是手动在txt中写入中文,则会乱码,我们不妨用“myfile5.txt”做测试,验证是否正确。

验证正确。
写了Java——InputStream与OutputStream流类 和 Reader与Writer流类。
**我有一丝丝疑问:**写入到文件里面需要先写入到缓存吗?
查阅了一下资料,得到了答案(可以点击进入原博文,侵权立删):
写入文件本质上是直接写入到磁盘中,而因为写文件本质是写磁盘,磁盘的速度远不如内存,所以频繁地写文件必然严重降低程序的运行效率。为此Java设计了缓存写入器BufferedWriter,它的write方法并不直接写入文件,而是先写入一块缓存,等到缓存写满了再将缓存上的数据写入文件。由于缓存空间位于内存之中,写入缓存等同访问内存,这样相当于把写磁盘动作替换成写内存动作,因此BufferedWriter的整体写文件性能要大大优于写入文件的类,同理BufferedReader也是如此。
3918

被折叠的 条评论
为什么被折叠?



