java filereader 示例_J04-Java IO流总结四 《 FileReader和FileWriter 》
FileReader和FileWriter的源碼相對(duì)簡(jiǎn)單,下面通過(guò)分析它們的源碼以更好地進(jìn)行理解這兩個(gè)流
1. FileReader
FileReader實(shí)現(xiàn)了讀取底層的字節(jié)數(shù)據(jù)并將其轉(zhuǎn)換為字符數(shù)據(jù)的功能,轉(zhuǎn)換時(shí)依賴的字符集為平臺(tái)默認(rèn)的字符集GBK(Windows平臺(tái))。
FileReader源碼如下:
public class FileReader extendsInputStreamReader {public FileReader(String fileName) throwsFileNotFoundException {super(newFileInputStream(fileName));
}public FileReader(File file) throwsFileNotFoundException {super(newFileInputStream(file));
}publicFileReader(FileDescriptor fd) {super(newFileInputStream(fd));
}
}
由源碼可以看出,FileReader類繼承自InputStreamReader類,它自己只提供了幾個(gè)構(gòu)造方法,它的構(gòu)造方法中又通過(guò)super來(lái)調(diào)用父類構(gòu)造器以構(gòu)建流對(duì)象,它本身沒(méi)有再提供其他的讀取流數(shù)據(jù)的方法,全部繼承它的直接父類InputStreamReader,而InputStreamReader又是繼承自Reader類,因此FileReader和InputStreamReader一樣,都能使用read()、read(char cbuf[])、read(char cbuf[], int off, int len)方法來(lái)讀取流數(shù)據(jù)。
此外,由源碼可知,FileReader的讀取字符串的功能是通過(guò)轉(zhuǎn)換流InputStreamReader類實(shí)現(xiàn)的:首先InputStreamReader包裝了一個(gè)FileInputStream從文件讀取字節(jié)數(shù)據(jù),再將讀取到的字節(jié)數(shù)據(jù)轉(zhuǎn)換為字符。而FileReader繼承了InputStreamReader,從而也獲得了該功能。我們截取該類的其中一個(gè)構(gòu)造方法的代碼出來(lái):
public FileReader(String fileName) throwsFileNotFoundException {super(newFileInputStream(fileName));
}
可以看到,在調(diào)用父類InputStreamReader的構(gòu)造方法時(shí),沒(méi)有顯式地指定解碼所需的字符集,因此使用的是平臺(tái)默認(rèn)字符集來(lái)將讀到的字節(jié)數(shù)據(jù)轉(zhuǎn)換為字符。因此,FileReader去讀取GBK編碼的源文件數(shù)據(jù)時(shí)不會(huì)出現(xiàn)亂碼,而在讀取UTF-8等其他字符集編碼的文件時(shí)就會(huì)粗現(xiàn)亂碼了。
從該流的API文檔同樣可以看出這點(diǎn):FileReader是用來(lái)讀取字符文件的便捷類。此類的構(gòu)造方法假定默認(rèn)字符編碼和默認(rèn)字節(jié)緩沖區(qū)大小都是適當(dāng)?shù)?。若要自己指定這些值,可以先在 FileInputStream 上構(gòu)造一個(gè) InputStreamReader。 FileReader 用于讀取字符流。要讀取原始字節(jié)流,請(qǐng)考慮使用 FileInputStream。
綜上,可知FileReader的本質(zhì)其實(shí)還是字節(jié)流!
FileReader類使用示例代碼:
importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;public classFileReaderTest {public static voidmain(String[] args) {
System.out.println("【從GBK文件讀取到的內(nèi)容】:");
test1();
System.out.println("\n\n【從UTF-8文件讀取到的內(nèi)容】:");
test2();
} /*** 使用FileReader從編碼為GBK的源文件1.txt中讀取數(shù)據(jù),能正確讀取*/
private static voidtest1() {
FileReader fr= null;try{
fr= new FileReader("./src/res/1.txt");int value = 0;while(-1 != (value = fr.read())) { //使用read()方法讀取
System.out.print((char)value);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally{if(null !=fr) {try{
fr.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
} /*** 使用FileReader從編碼為utf-8的源文件2.txt中讀取數(shù)據(jù),將出現(xiàn)亂碼*/
private static voidtest2() {
FileReader fr= null;try{
fr= new FileReader("./src/res/2.txt");int len = 0;char[] buf = new char[1024]; //注意這里是字符數(shù)組!!
while(-1 != (len = fr.read(buf))) { //使用read(char cbuf[])方法讀取
System.out.println(newString(buf));
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally{if(null !=fr) {try{
fr.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
}
代碼運(yùn)行效果:
【從GBK文件讀取到的內(nèi)容】:
hello java hello hello 中國(guó)
【從UTF-8文件讀取到的內(nèi)容】:
hello java hello hello 涓浗
可見(jiàn),若是使用FileReader從UTF-8文件中讀取數(shù)據(jù),將會(huì)出現(xiàn)亂碼,原因在上面也說(shuō)了,是因?yàn)镕ileReader的底層轉(zhuǎn)換流InputStreamReader在將字節(jié)數(shù)據(jù)轉(zhuǎn)換為字符數(shù)據(jù)時(shí),使用的是平臺(tái)默認(rèn)的字符集GBK,與源文件的不一致,由此導(dǎo)致了亂碼。
2. FileWriter
FileWriter實(shí)現(xiàn)了將字符數(shù)據(jù)轉(zhuǎn)換為字節(jié)數(shù)據(jù)的功能。它所依賴的字符集也是平臺(tái)默認(rèn)的GBK 。
API文檔中關(guān)于FileWriter有如下描述:用來(lái)寫入字符文件的便捷類。此類的構(gòu)造方法假定默認(rèn)字符編碼和默認(rèn)字節(jié)緩沖區(qū)大小都是可接受的。若想要自己指定這些值,可以先在 FileOutputStream 上構(gòu)造一個(gè) OutputStreamWriter。
FileWriter源碼如下:
public class FileWriter extendsOutputStreamWriter {public FileWriter(String fileName) throwsIOException {super(newFileOutputStream(fileName));
}public FileWriter(String fileName, boolean append) throwsIOException {super(newFileOutputStream(fileName, append));
}public FileWriter(File file) throwsIOException {super(newFileOutputStream(file));
}public FileWriter(File file, boolean append) throwsIOException {super(newFileOutputStream(file, append));
}publicFileWriter(FileDescriptor fd) {super(newFileOutputStream(fd));
}
}
由FileWriter的源碼可以看到,該類的直接父類是轉(zhuǎn)換流OutputStreamWriter,它跟FileReader簡(jiǎn)直一模一樣——自己只提供了幾個(gè)構(gòu)造方法,并在它的構(gòu)造方法中又通過(guò)super來(lái)調(diào)用父類構(gòu)造器以構(gòu)建流對(duì)象,它本身沒(méi)有再提供其他的寫出流數(shù)據(jù)的方法,全部繼承它的直接父類OutputStreamWriter,而OutputStreamWriter又是繼承自Writer類,因此FileWriter和OutputStreamWriter一樣,都能使用write(int c)、write(char cbuf[])、write(char cbuf[], int off, int len)、write(String str)、write(String str, int off, int len)方法來(lái)寫入流數(shù)據(jù)。
FileWriter流使用示例代碼:
importjava.io.FileWriter;importjava.io.IOException;public classFileWriterTest {public static voidmain(String[] args) {
FileWriter fw= null;try{
fw= new FileWriter("./src/res/3.txt");
String str1= "hello java";
String str2= "中國(guó)";char[] array = str1.toCharArray();//將字符串轉(zhuǎn)換為字符數(shù)組
fw.write(str1,0, 5); //寫入:hello
fw.write(str2); //寫入:中國(guó)
fw.write(array); //寫入:hello java
fw.write(array, 6, 4); //寫入:java
}catch(IOException e) {
e.printStackTrace();
}finally{if(null !=fw) {try{
fw.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
}
代碼運(yùn)行效果:
本次示例中,是將數(shù)據(jù)寫入GBK編碼的目標(biāo)文件中,倘若目標(biāo)是UTF-8或者其他編碼,則寫入的數(shù)據(jù)中文會(huì)發(fā)生亂碼,如下所示:
使用FileReader和FileWriter在兩個(gè)文件之間相互拷貝文件的操作跟前邊的示例差不多,這里不再寫了。
3. 小結(jié)
FileInputStream、FileOutputStream、FileReader和FileWriter都是跟磁盤文件有關(guān)的字節(jié)流或字符流,但凡需要跟磁盤文件進(jìn)行I/O操作的,必將使用到它們中的其中一個(gè)。需要根據(jù)讀取的是字節(jié)流還是字符流來(lái)進(jìn)行相應(yīng)的選擇。
總結(jié)
以上是生活随笔為你收集整理的java filereader 示例_J04-Java IO流总结四 《 FileReader和FileWriter 》的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 抵押车找不到车主怎么绑定12123?
- 下一篇: java 不识别enum_关于java: