IO流分为字符流和字节流,字符流的抽象基类是Reader和Writer,而字节流的抽象基类OutputStream InputStream.
当然也可以将IO流分为输入流和输出流。
代码示例:
public static voia main(String[] args)throws IOException {//为了演示,抛出异常
FileWriter fw=new FileWriter("kingkong.txt");
fw.write("I am hero.");
fw.flush();
//close和flush区别是,flush刷新后会继续使用
fw.close();
}
对于异常处理方式:
FileWriter fw=null;
try{
fw=new FileWriter("demo.txt");
fw.write("weizhenhua");
}
catch(IOException e){e.printStack();}
finally
{
try{
//当fw创建不成功的时候,fw不能使用close方法,所以进行判断
if(fw!=null)
fw.close();
}
catch(IOException e) {e.printStack();}
}
文本文件的读取流对象
FileReader fr=new FileReader("demo.txt");
fr.read();
read一次读一个字符,且自动往下读
定义一个字符数组,用于存储读到字符
该read(char[])返回的是读到字符个数
char[] buf=new char[4];
int num=fr.read(buf);
fr.close();
实例代码:
public static void main(String[] args)throws IOException
{
FileReader fr=new FileReader("demo.txt");
char[] buf=new char[1024];
int num=0;
while((num=fr.read(buf))!=-1){System.out.println(new String(buf,0,num));}
fr.close();
}
//在D盘创建一个文件,用于存储C盘文件中的数据
//定义读取流和C盘文件关联
//通过不断的读取完成数据存储
//关闭资源
class CopyText{
public static void copy_1()throws IOException{
//创建目的地址
FileWriter fw=new FileWriter("d:\destination.txt");
//C盘文件中读取一个字符,再往D盘写一个字符
FileReader fr=new FileReader("c:\resourse.txt");
int ch=0;
while((ch=fr.read())!=-1){
fw.write(ch);
}
fw.close();
fr.close();
}
public static void copy_2()
{
FileWriter fw=null;
FileReader fr=null;
try{
fw=new FileWriter("d:\destination.txt");
fr=new FileReader("c:\resourse.txt");
char[] buf=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1){
fw.write(buf,0,len);
}
}
catch()
{
throw new RuntimeException("读写失败");
}
finally{
if(fr!=null)
try{fr.close();}
catch(IOException e){}
if(fw!=null)
try{fw.close();}
catch(IOException e){}
}
}
}
-------------------------------------------------
字符流的缓冲区
缓冲在创建缓冲区之前,必须要先有流对象
//创建一个字符写入流对象
FileWriter fw=new FileWriter("buf.txt");
BufferedWriter bufw=new BufferedWriter(fw);
bufw.write("weizhenhua");
//只要用到缓冲区,必须刷新
bufw.flush();
//关闭缓冲区就是在关闭缓冲区中的流对象
bufw.close();
fw.close();
BufferedReader
//创建一个读取流对象和文件相关联
FileReader fr=new FileReader("buf.txt");
BufferedReader bufr=new BufferedRead(fr);
//readLine是整行读取
String line=null;
while((line=bufr.readLine())!=null){}
bufr.close();
运用缓冲区复制文本文件
public static void main(String[] args){
BufferedReader bufr=null;
BufferedWriter bufw=null;
try{
bufr=new BufferedReader(new FileReader("a.txt"));
bufw=new BufferdeWriter(new FileWriter("b.txt"));
String line=null;
while((line=bufr.readLine())!=null){
bufw.write(line);
bufw.flush();
}
}
catch(IOException e)
{throw new RuntimeException("failed");}
finally{
try{
if(bufr!=null)
bufr.close);
}catch(IOException e){throw new RuntimeException("failed");}
try{
if(bufw!=null)
bufw.close();
}catch(IOException e){throw new RuntimeException("failed");}
}
}
readLine方法返回的时候不返回回车符
readLine方法原理:无论是读一行,还是读取多个字符,都是一个一个的读取字符,read()
readLine实例代码:
Public String myReadLine()throws IOException{
FileRaader fr=new FileReader("a.txt");
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=fr.read())!=-1){
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
装饰设计模式
class MyBufferedReader{
private FileReader r;
MyBufferedReader(FileReader r){
this.r=r;
}
}
当想要对已有的对象进行功能增强时,可以定义类,将已经有的对象传入,基于已有功能,并提供加强功能
那么自定义的类称为装饰类。
装饰比继承灵活,避免了继承体系的臃肿。
FileReader fr=new FileReader("a.txt");
LineNumberReader lnr=new LineNumberReader(fr);
String line=null;
lnr.setLineNumber(22);
while((line=lnr.readerLine())!=null){}lnr.close();
包装类MyLineNumberReader
class MyLineNumberReader{
private Reader r;
private int lineNumber=0;
MyLineNumberReader(Reader r){
this.r=r;
}
public int getLineNumber(){
return this.lineNumber;
}
public void setLineNumber(int lineNum){
this.lineNumber=lineNum;
}
Public String myReadLine()throws IOException{
lineNumber++;
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1){
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
}