JavaIO流 FileReader和FileWriter

FileWriter类

FileWriter类可以把字符直接写入流中,FileWriter继承与OutputStreamWriter,它的所有方法也都继承于OutputStreamWriter

继承关系

1
2
3
4
5
java.lang.Object
|----> java.io.Writer
|----> java.io.OutputStreamWriter
|----> java.io.FileWriter

构造方法:

方法 描述
FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(File file, boolean append) 根据给定的 File 对象构造一个 FileWriter 对象。是否追加写入
FileWriter(FileDescriptor fd) 构造与某个文件描述符相关联的 FileWriter 对象。
FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append) 根据给定的文件名以及指示是否追加加写入数据的 boolean 值来构造 FileWriter 对象。

读操作方法

OutputStreamWriter继承的方法:

方法 描述
void write(int c) 写入单个字符。
void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
void write(String str, int off, int len) 写入字符串的某一部分。
String getEncoding() 返回此流使用的字符编码的名称。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。

FileWriter类和OutputStreamWriter类的区别

还是和上面的一样,区别主要在构造方法上。
OutputStream类的构造方法:

方法 描述
OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, Charset cs) 创建使用给定字符集的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建使用给定字符集编码器的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。
从OutputStreamWriter的构造方法中可看出,第一个参数为OutputStream,第二个参数可以是字符编码或者编码器。所以写操作时需要指定字符编码的时候必须使用OutputStreamWriter

FileWriter的构造方法中第一个参数为File,String,FileDescriptor对象,第二个参数表示可以是否追加写入。FileWriter会使用默认的编码来进行写操作。所以使用File类或String文件名来进行写操作是使用FileWriter,要求追加写入文件时也要使用FileWriter

读写实例:复制文件

使用FileReader和FileWriter复制文件

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
39
40
41
42
43
44
45
46
47
48
49
/**   
* 从名字为from的源文件复制到名字为to的目的文件中。
* @param from 源文件
* @param to 目的文件
*/
public static void copyByFileReader_Writer(String from, String to)
{
FileReader reader = null;
FileWriter writer = null;
try
{
reader = new FileReader(from);
writer = new FileWriter(to);
char[] cbuf = new char[128];
int size = 0;
while ((size = reader.read(cbuf, 0, cbuf.length)) != -1)
{
writer.write(cbuf, 0, size);
}
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (reader != null)
try
{
reader.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (writer != null)
try
{
writer.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

main方法中调用:

1
2
3
4
5
6
public static void main(String[] args)
{
String from = "gbk.txt";
String to = "gbk_copy.txt";
copyByFileReader_Writer(from, to);
}

源文件gbk.txt:

1
2
gbk file
这里是一句中文

复制要的目的文件gbk_copy.txt

1
2
gbk file
这里是一句中文

编码问题

使用FileReader和FileWriter使用默认的编码来读文件,写文件。这样容易出现问题。现在项目的编码是gbk的,但是此时用来复制utf-8编码的文件就会出现问题。
源文件utf8.txt(utf-8编码):

1
2
utf-8 file
这里是一句中文

main方法:

1
2
3
4
5
6
public static void main(String[] args)
{
String from = "utf8.txt";
String to = "utf8_copy.txt";
copyByFileReader_Writer(from, to);
}

运行结果,复制好的utf8_copy.txt中的内容:

1
2
utf-8 file
杩欓噷鏄竴鍙ヤ腑鏂�

出现这样的乱码是因为,我们现在是以默认的编码(gbk)打开的,现在改成以utf-8编码打开看看:

1
2
utf-8 file
这里是一句中�?

可以看到虽然已经以utf-8编码打开了,但是还是显示乱码。

所以遇到需要处理字符编码的时候要使用InputStreamReaderOutputStreamWriter来操作。