java.io包中:字符流
字符流的两个抽象基类:
Reader Writer
文件的读取:Reader抽象类(java.io包中)
直接子类的构造方法:
FileReader(File file)
在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(FileDescriptor fd)
在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。
FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新 FileReader。
int read()读取单个字符
注意:作为整数读取的字符,范围在0到65535之间(0x00-0xffff),如果已到达流的末尾,则返回 -1
int read(char[] cbuf) 将字符读入数组。
注意:读取的字符数,如果已到达流的末尾,则返回 -1
//例子1:使用read()读取单个字符并输出
import java.io.*; class FileReaderDemo { public static void sop(Object obj) { System.out.print(obj); } public static void main(String[] args)throws IOException { //创建一个文件读取流对象,和指定名称的文件相关联起来。 //要保证该文件是已经存在的。如果不存在,会发生异常,即FileNotFoundException FileReader fr = new FileReader("F:\myfile\test.txt"); //调用读取流对象的read方法。 //read方法:一次读取一次字符,而且会自动往后面读取字符。 int ch = 0; while((ch=fr.read())!=-1) { sop((char)ch); } /* while(true) { int ch = fr.read(); if(ch==-1) break; sop((char)ch); //读取文件中的一个字符 } */ fr.close(); } }
//例子2:使用read(char[] cbuf) 将字符读入数组再输出
import java.io.*; class FileReaderDemo2 { public static void sop(Object obj) { System.out.print(obj); } public static void main(String[] args)throws IOException { //创建一个文件读取流对象,和指定名称的文件相关联起来。 //要保证该文件是已经存在的。如果不存在,会发生异常,即FileNotFoundException FileReader fr = new FileReader("F:\myfile\test.txt"); //定义一个字符数组,用于存储读取的字符 char[] buf = new char[1024]; int num = 0; while((num = fr.read(buf))!=-1)//num = fr.read(buf)返回是读取的字符个数,如果已到达流的末尾,则返回 -1 { //String(char[] value, int offset, int count) 分配一个新的 String,它包含取自字符数组参数一个子数组的字符。 String str = new String(buf,0,num); sop(str); } fr.close(); } }
那么再学习字符写入流的特点:Writer 抽象类(java.io包中)
FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。
既然IO流是用于操作数据的,那么数据的最常见体现形式是:文件
那么先以操作文件为主来显示。
需求:在硬盘上,创建一个文件夹并写入一些文字数据。后缀名是父类名,前缀名是该流对象的功能。
找到一个专门用于操作文件的Writer子类对象。
public abstract void close()
throws IOException关闭此流,但要先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。
关闭以前关闭的流无效。
abstract void flush()
刷新该流的缓冲。
//例子3:
import java.io.*; class FileWriterDemo { public static void main(String[] args) throws IOException { //第一步: //创建一个FileWriter对象,该对象一被初始化就必须有明确的被操作的文件,而且该文件会被创建到指定的目录下 //如果该目录下已有同名文件,将会被覆盖。其实该步就是要明确数据要存放的目的地。 FileWriter fw = new FileWriter("F:\myfile\demo.txt"); //第二步: //调用父类共性方法write方法,将数据写入到了流当中。 fw.write("asjdsjdfkskidkf,fdhjsdkjfdsk,dfhjdskj"); //第三步: //调用父类共性方法flush方法,刷新流对象中的缓冲中的数据,将数据刷新到目的地中。 fw.flush(); //可以接着往目的地中写入数据 fw.write("xiayuanquan"); fw.flush(); //父类中的共性方法close方法,关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷新到目的地中去。 //和flush的区别:flush刷新后,流可以继续使用;而close刷新后,流会关闭,无法继续使用。 fw.write(" aaaaaaaaaaaaaa"); fw.close(); //Stream closed //fw.write("xxxx"); //流已关闭,此时不能再向目的地的文件中写入数据 } }
使用字符流读取和写入数据时,可能会出现流异常的情况,例如文件不存在、路径错误等,此时,需要我们对异常进行捕获并处理。
//例子4:
import java.io.*; class FileWriterExceptionDemo { public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter("F:\myfile\Exception.txt");//创建目标文件 fw.write("my name is xiayuanquan!"); //往流里写入数据内容 } catch(IOException ie) { System.out.println(ie.toString()); } finally { try { if(fw!=null) fw.close(); //先刷新流,将流中的数据内容刷到目标文件中,然后关闭流资源 } catch(IOException ie) { System.out.println(ie.toString()); } } } }
拓展:当用户想把数据写入同一个文件,可是文件中已经存在内容时,那么新写入的数据会替换之前的数据。此时,这不是用户所希望的,针对这种情况,我们可以将新写入的内容在文件内容后面续写即可。api中就提供了一个方法如下:
对已有文件数据内容的续写:
FileWriter(File file, boolean append)
根据给定的 File 对象构造一个 FileWriter 对象。
//例子5:
import java.io.*; class FileWriterDemoappend { public static void main(String[] args) { FileWriter fw = null; try { //传递一个ture参数,代表不覆盖已有的文件。并在已有文件的末尾处进行文件的续写。 fw = new FileWriter("F:\myfile\demo.txt",true); fw.write(",,,wei-zhong-hua-jue-qi-er-du-shu"); fw.write(" abc=abc");//' '代表换行,然后接着续写数据 } catch(IOException e) { System.out.println(e.toString()); } finally { try { if(fw!=null) fw.close(); } catch(IOException e) { System.out.println(e.toString()); } } } }
综合练习:将相同目录下一个文本文件赋值到另一个文本文件中。
(例如:将F:\myfile\practice.txt--------->F:\myfile\test.txt)
思路:第一步,创建读取流与F:\myfile\practice.txt相关联。
第二步,将F:\myfile\practice.txt中数据内容全部读入流中,并放在定义的数组内,然后关闭资源。
第三部,创建写入流与F:\myfile\test.txt相关联,并设置续写功能的布尔值为true;
第四部,将第二部定义的数组的数据内容全部写入F:\myfile\test.txt文件中,然后关闭资源。
//例子6:
import java.io.*; class CopyText { public static void main(String[] args)throws IOException { FileReader fr = new FileReader("F:\myfile\practice.txt"); FileWriter fw = new FileWriter("F:\myfile\test.txt",true); //第一种方式:(先全部读完数据后存入缓冲区,再一次性续写入目标文件中) int num=0; char[] buf = new char[1024]; while((num = fr.read(buf))!=-1) { String str = new String(buf,0,num); fw.write(" "+str); // fw.write(buf,0,num); fw.close(); } fr.close(); /* //第二种方式:(每次读一个数据,就往目标文件中写入一个数据) int num = 0; while((num = fr.read())!=-1) { fw.write(num); } fw.write(" "); fw.close(); fr.close(); */ } }