黑马程序员_毕向东_Java基础_DAY18-19_IO基础、字符流

来源:互联网 发布:灰色关联软件gm 编辑:程序博客网 时间:2024/05/09 00:44

----------- android培训、java培训、期待与您交流! ------------

I/O基础知识

基本概念:

I/O : Input/Output 输入输出

IO流即是输入输出流,用来处理设备之间数据的传输、流向

java对数据的操作是通过流的方式

java用于操作流的对象都在IO包中

 

分类:

按操作数据分为两种:字节流与字符流

早期都是字节流,可以处理所有数据。

后期由于文本处理是常见的处理方式,因此设置了字符流。

字符流在内部融合了码表,可以由用户来指定。

常用编码格式有:

ASCII

GBK

unicode

UTF-8

UTF-16

按流向分为:输入流、输出流

 

常见IO类

字节流抽象基类:

InputStream

OutputStream

字符流抽象基类:

Reader

Writer

由这四个基类派生出来的子类名称都以其父类名作为后缀,如:

FileInputStream

FileReader

  

字符流

Writer类

 java.io.Writer

     java.io.OutputStreamWriter

         java.io.FileWriter

 OutputStreamWriter 是一个public类,称为转换流。它是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

FileWriter是OutputStreamWriter的唯一子类,用来写入字符文件的便捷类,可以用于写入字符流。

FileWriter没有空参数构造器,必须指定目标文件。没有特有方法。

 

构造器:

FileWriter(String filename)

 创建FileWriter对象:

FileWriter fw = newFileWriter("demo.txt");

 

注意:指定的文件路径中的\需要转义。

如果指定的文件存在,则,覆盖此文件。

如果指定文件不存在,但路径存在,则会创建此文件。

如果路径不存在,则抛出异常。

创建FileWriter类对象可能会抛出java.io.IOException异常,因此要么throws要么catch。

 

fw.write("要存入的数据"); //将数据写到流中,此时还没有进文件内

fw.append();//和write差不多,但是可以使用方法调用链

fw.append("abc\r\n").append("def\r\n");

 

注意:

enter+newline with different platforms:

windows:  \r\n

mac:      \r

unix/linux: \n

 在windows下直接使用\n不能换行,而是显示一个黑方块。这就是使用记事本打开java原码文件格式混乱的原因。

 

fw.flush(); //刷新流对象中的缓冲区中的数据,清空并将其转入文件中。

close(); //关闭流资源,并刷新缓冲区。

注意:java中的输入流是调用了操作系统的功能(资源),如果不用了一定要close来释放资源。

 

文件续写:

直接使用FileWriter fw = newFileWriter("demo.txt");时覆盖源文件,如果想在文件后添加内容,则可以使用另一个构造器。

FileWriter fw = newFileWriter("demo.txt", true);

这种方式在文件存在的情况下不会覆盖原文件,而是直接再此文件的内容后添加数据。

  

FileReader类

java.lang.Object

 java.io.Reader

     java.io.InputStreamReader

         java.io.FileReader

 

构造器:

FileReader(String filename) throws FileNotFoundException

FileNotFoundException是IOException的一个子类。

当指定的文件不存在时,会抛出此异常。

FileReader fr = newFileReader("demo.txt");

System.out.println(fr.read());

fr.close();

 

注意:

read()方法用于读取一个字符,但返回的字符是int型的,所以需要强制类型转换(char)fr.read()。

 read()方法是依次向后读取,如果读到末尾(文件的结束标记),则返回-1。

 

读取方式:(一次读一个字符)

int ch = 0;

while((ch = fr.read()) != -1)){

       fw.write(ch);

}

  

另一种读取方式:(一次读2KB)

char[] buffer = new char[1024];

int len = 0;

while((len = fr.read(buffer)) != -1){

       fw.write(buffer,0, len);

}

 关于IOException 的处理:

可以直接使用throw newRuntimeException();的方式来强制结束程序。

打开多个流时,在finally块中要依次关闭。

 

练习:

 //: IOExceptionDemo.java//IO异常处理基本格式 import java.io.FileWriter;import java.io.IOException; class IOExceptionDemo{       publicstatic void main(String[] args)       {              FileWriterfw = null;              try{                     fw= new FileWriter("demo.txt");                     fw.write("我整个人都斯巴达了!\r\n");                     fw.append("我整个人都斯巴达了!\r\n").append("这就是斯巴达!!\r\n");              }              catch(IOExceptione){                     System.out.println("发生了IO异常!" +e.toString());              }              finally{                     try{                            if(fw!= null)                                   fw.close();                     }                     catch(IOExceptione){                            System.out.println("发生了IO异常!" +e.toString());                     }              }       }}

  

//: FileReaderDemo.java//读取文本文件 import java.io.FileReader;import java.io.IOException; class FileReaderDemo {       publicstatic void main(String[] args) {              FileReaderfr = null;              try{                     fr= new FileReader("demo.txt");                     char[]buffer = new char[1024];                     intnum = 0;                     while((num= fr.read(buffer)) != -1)                            System.out.println(newString(buffer, 0, num));              }              catch(IOException e){                     System.out.println("发生了IO异常::" +e.toString());              }              finally{                     try{                            if(fr!= null)                                   fr.close();                     }                     catch(IOException e){                            System.out.println("发生了IO异常::" +e.toString());                     }              }       }}
 

//: CopyTextDemo.java//分别使用单字符的buf,和char[]进行文本文件的复制 import java.io.FileReader;import java.io.FileWriter;import java.io.IOException; class CopyTextDemo{       publicstatic void main(String[] args) {              copyChar();              copyCharArr();       }       publicstatic void copyChar(){              FileReaderfr = null;              FileWriterfw = null;              try{                     fr= new FileReader("demo.txt");                     fw= new FileWriter("d:\\demo.txt");                     intch = 0;                     while((ch = fr.read()) != -1)                            fw.write(ch);              }              catch(IOException e){                     System.out.println("发生了IO异常::" +e.toString());              }              finally{                     try{                            if(fr != null)                                   fr.close();                     }                     catch(IOException e){                            System.out.println("发生了IO异常::" +e.toString());                     }                                        try{                            if(fw!= null)                                   fw.close();                     }                     catch(IOException e){                            System.out.println("发生了IO异常::" +e.toString());                     }              }       }        publicstatic void copyCharArr(){              FileReaderfr = null;              FileWriterfw = null;              try{                     fr= new FileReader("demo.txt");                     fw= new FileWriter("d:\\demo.txt", true);                     char[]buffer = new char[1024];                     intnum = 0;                     while((num = fr.read(buffer)) != -1)                            fw.write(buffer,0, num);              }              catch(IOException e){                     System.out.println("发生了IO异常::" +e.toString());              }              finally{                     try{                            if(fr != null)                                   fr.close();                     }                     catch(IOException e){                            System.out.println("发生了IO异常::" +e.toString());                     }                                        try{                            if(fw!= null)                                   fw.close();                     }                     catch(IOException e){                            System.out.println("发生了IO异常::" +e.toString());                     }              }       }}

字符流缓冲区:

BufferedWriter

 java.lang.Object

 java.io.Writer

     java.io.BufferedWriter

它没有空参数构造器,在创建对象时必须指定目标Writer对象。

这是因为缓冲区是为了提高流的操作效率而出现的。

所以在创建缓冲区之前,必须先有流对象。

 

构造器:

BufferedWriter(Writer out)

         创建一个使用默认大小输出缓冲区的缓冲字符输出流。

BufferedWriter(Writer out, int sz)

         创建一个使用给定大小输出缓冲区的新缓冲字符输出流。

 

方法:

 voidclose()

         关闭此流,但要先刷新它。

 voidflush()

         刷新该流的缓冲。

 void newLine()

         写入一个行分隔符。

 voidwrite(char[] cbuf, int off, int len)

         写入字符数组的某一部分。

 voidwrite(int c)

         写入单个字符。

 voidwrite(String s, int off, int len)

         写入字符串的某一部分。

write方法可以用于写入字符、字符串、字符数组

 

BufferedReader

 java.lang.Object

 java.io.Reader

     java.io.BufferedReader

 使用上与BufferedWriter大致相同。

 包含特殊方法:

String readLine()读取一个文本行。

 

练习:

//: BufferedTest.java//使用字符缓冲流进行文本文件复制操作 import java.io.*; class BufferedTest{       publicstatic void main(String[] args)       {              BufferedReaderbuffr = null;              BufferedWriterbuffw = null;              try              {                     buffr= new BufferedReader(new FileReader("demo.txt"));                     buffw= new BufferedWriter(new FileWriter("buffDemo.txt"));                     Stringstr = null;                     while((str= buffr.readLine()) != null){                            buffw.write(str);                            buffw.newLine();                            buffw.flush();                     }              }              catch(IOException e)              {                     thrownew RuntimeException("文件复制发生错误");              }              finally{                     if(buffr!= null){                            try                            {                                   buffr.close();                            }                            catch(IOException e)                            {                                   thrownew RuntimeException("关闭输入流时发生错误");                            }                     }                     if(buffw!= null){                            try                            {                                   buffw.close();                            }                            catch(IOException e)                            {                                   thrownew RuntimeException("关闭输出流时发生错误");                            }                     }              }       }}

 

自定义类模拟字符缓冲流: 

//: MyBufferedReaderTest.java//使用自定义类模拟BufferedReader功能 import java.io.*; class MyBufferedReader{       Readerfr;       MyBufferedReader(Readerfr){              this.fr= fr;       }       publicString readLine() throws IOException{              StringBuildersb = new StringBuilder();              intch = 0;              while((ch= fr.read()) != -1){                     if(ch== '\r')                            continue;                     if(ch== '\n')                            returnsb.toString();                     else                            sb.append((char)ch);              }              if(sb.length()!= 0)                     returnsb.toString();              returnnull;       }       publicvoid close() throws IOException{              fr.close();       }} class MyBufferedReaderTest{       publicstatic void main(String[] args)       {              MyBufferedReaderbuffr = null;              BufferedWriterbuffw = null;              try              {                     buffr= new MyBufferedReader(new FileReader("demo.txt"));                     buffw= new BufferedWriter(new FileWriter("123.txt"));                     Stringstr = null;                     while((str= buffr.readLine()) != null){                            buffw.write(str);                            buffw.newLine();                            buffw.flush();                     }              }              catch(IOException e)              {                     thrownew RuntimeException("文件复制发生错误");              }              finally{                     if(buffr!= null){                            try                            {                                   buffr.close();                            }                            catch(IOException e)                            {                                   thrownew RuntimeException("关闭输入流时发生错误");                            }                     }                     if(buffw!= null){                            try                            {                                   buffw.close();                            }                            catch(IOException e)                            {                                   thrownew RuntimeException("关闭输出流时发生错误");                            }                     }              }       }}

 

装饰设计模式:

当想要对已有的对象进行功能增强时,

可以定义一个新类,将已有对象传入(组合),基于已有的功能,并提供加强功能。

那么自定义的该类称为装饰类。

 

装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。

所以装饰类和被装饰类通常都属于一个体系中,表示只要只某某的子类,我全能进行增强。

 

事实上字符缓冲流使用的就是装饰设计模式。

 

LineNumberReader

 

java.lang.Object

 java.io.Reader

     java.io.BufferedReader

         java.io.LineNumberReader

 

LineNumberReader是BufferedReader的子类,包含父类的所有功能。

在此基础上,还添加了两个新方法:

 

int getLineNumber() //获取当前行号

void setLineNumber() //设置当前行号

 

设计自定义类模拟LineNumberReader的功能:

//: MyLineNumberReader.java//自定义类模拟LineNumberReader类 import java.io.*; class MyLineNumberReader extendsMyBufferedReader{       privateint lineNumber = 0;        publicMyLineNumberReader(Reader r){              super(r);       }       publicint getLineNumber(){              returnlineNumber;       }       publicvoid setLineNumber(int num){              this.lineNumber= num;       }        publicString readLine() throws IOException{              lineNumber++;              returnsuper.readLine();       }        publicstatic void main(String[] args)       {              MyLineNumberReadermyline = null;              BufferedWriterbw = null;              try              {                     myline= new MyLineNumberReader(new FileReader("demo.txt"));                     bw= new BufferedWriter(new FileWriter("myline.txt"));                     Stringstr = null;                     while((str = myline.readLine()) != null)                     {                            bw.write(myline.getLineNumber()+ ": " + str);                            bw.newLine();                            bw.flush();                     }              }              catch(IOException e)              {                     thrownew RuntimeException("读写文件时发生错误");              }              finally{                     if(myline!= null){                            try                            {                                   myline.close();                            }                            catch(IOException e)                            {                                   thrownew RuntimeException("关闭输入流时发生错误");                            }                     }                     if(bw!= null){                            try                            {                                   bw.close();                            }                            catch(IOException e)                            {                                   thrownew RuntimeException("关闭输出流时发生错误");                            }                     }              }       }}


----------- android培训、java培训、期待与您交流! ------------

原创粉丝点击