奋斗黑马程序员----Java缓冲区简介

来源:互联网 发布:网络套现违法吗 编辑:程序博客网 时间:2024/06/04 17:40
----------android培训java培训、期待与您交流! ----------
/** * Java之IO小结2:缓冲区 *  * 1 :字符流的缓冲区 * 2 :字符读取流缓冲区 * 3 :练习,通过缓冲区复制一个.java文件 * 4 :自定义ReadLine的实现。(结合ReadLine原理) * 5 :LineNumberReader对象 * 6 :LineNumberReader原理介绍和模拟 *//** 1 :字符流的缓冲区 * 缓冲区的出现,提高了对数据的读写效率。 * 对应类: * BufferedWriter * BufferedReader *  * public class BufferedWriter extends Writer *   将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。  *   可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。  *   该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性  * line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用 * 此方法来终止每个输出行要优于直接写入新行符。  *   通常 Writer 将其输出立即发送到底层字符或字节流。除非要求提示输出,否则建议 * 用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters * 和 OutputStreamWriters)。例如,  *   PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out"))); *   * public class BufferedReader extends Reader *   从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。  *   可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。  *   通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。 * 因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader( * 如 FileReader 和 InputStreamReader)。例如,  *    BufferedReader in = new BufferedReader(new FileReader("foo.in")); *    *  缓冲区要结合流才能使用,必须先有流 *  在流的基础上,对流的功能进行了增强。。 *  * 缓冲区是为了,提高流的操作效率而出现的。所以在创建缓冲区之前,必须要先有流对象。 *  * 该缓冲区中提供了一个“跨平台”的换行符(换行方法):newLine(); */import java.io.*;public class BufferedWriterDemo {public static void main(String[] args) throws IOException {//创建一个字符写入流对象FileWriter fw = new FileWriter("buf.txt");/* * 其实缓冲区的底层原理还是在内部封装了一个数组。  *//* * BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。 *  * 为了提高字符写入流效率,加入了缓冲技术 * 只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。 *  * void newLine() 写入一个行分隔符。  */BufferedWriter bufw = new BufferedWriter(fw);bufw.write("abddadf");bufw.newLine();//底层:windows:\r\nlinux:\nfor(int x=1;x<5;x++){bufw.write("adajkdf---"+x+"----XXOO----");bufw.newLine();bufw.flush();//这个最好写了,假如运行过程中停电了,这句代码就显得特别重要了。。}/** * 记住:只要用到缓冲区,就要记得刷新。 */bufw.flush();/* * 其实关闭缓冲区,就是在关闭缓冲区中的流对象。因此,不必用fw.close(); */bufw.close();}}/** 2 :字符读取流缓冲区 *  *    public class BufferedReader extends Reader从字符输入流中读取文本,缓冲 * 各个字符,从而实现字符、数组和行的高效读取。 *   * 本身是Reader的子类,继承了Reader的方法。 *  * 该缓冲区提供了一个一次读一行的方法ReadLine,方便与对文本数据的获取。 * 当返回null时,表示读到文件的末尾。。 *  * ReadLine方法返回的时候只返回回车符之前的数据内容,并不返回回车符。 */import java.io.*;public class BufferedReaderDemo {public static void main(String[] args) throws IOException {/* * 创建一个读取流对象和文件相关联。 */ FileReader fr = new FileReader("buf.txt");/* * BufferedReader(Reader in)  创建一个使用默认大小输入缓冲区的缓冲字符输入流。 *  * 为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数。 */ BufferedReader bufr = new BufferedReader(fr);  /*public String readLine() throws IOException读取一个文本行。通过下列字符之一  *  即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。  * 返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null  *   *  readLine();每运行一次,则readLine()会自动指向下一行。  */ String st = bufr.readLine(); //读一行。 如果有很多行的数据,要很多次,就很麻烦。那么该怎么解决呢? System.out.println("st:"+st);  /*  * 由于ReadLine的返回值是String类型的。那么怎么循环读呢?  * 一行一行的读是最方便的。。  */ String line = null; while((line=bufr.readLine())!=null) { System.out.println(line); }  bufr.close();}}/** 3 :练习,通过缓冲区复制一个.java文件 * * 两个都要用 */import java.io.*;public class CopyTextBuBuf {public static void main(String[] args){BufferedReader bufr = null;BufferedWriter bufw = null;try{/*BufferedWriter bufw = new BufferedWriter(new FileWriter("BufferedWriterDemo_copy.java",true)); * 可以这么搞 */bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));bufw = new BufferedWriter(new FileWriter("BufWriter_Copy.txt"));String line = null;//中转站。之前的用的是一个数组中转站。while((line=bufr.readLine())!=null)//ReadLine();一次读一行,不报行终止符{bufw.write(line);/* * 如果此处没有换行的话,复制的文件里面的格式很乱。所以加上换行,会保留原来的格式。 */bufw.newLine();bufw.flush();}}catch(IOException e){throw new RuntimeException("读写失败");}finally{try{if(bufr!=null){bufr.close();}}catch(IOException e){throw new RuntimeException("读取关闭失败");}try{if(bufw!=null){bufw.close();}}catch(IOException e){throw new RuntimeException("写入关闭失败。");}}}}/** * 要明白ReadLine原理: *//**ReadLine原理介绍,见图例介绍 * 其实,readLine的原理还是read和缓冲区技术的集合。当readLine工作时,会先把换行符之前的数据都放到 * 一个缓冲区(内部的数组中),直到遇到换行符,然后就把这一行数据以String的形式返回。 */ /** 4 :自定义ReadLine的实现。(结合ReadLine原理) *  * 搞个类,功能类似BufferedReader * 明白了BufferedReader类中特有方法ReadLine的原理后,可以自定义一个类,包含一个功能 * 和ReadLine一致的方法。来模拟一下BufferedReader *  * 模拟readLine的实现。 */import java.io.*;class MyBufferedReader{private FileReader r;MyBufferedReader(FileReader r){this.r = r;}/* * 可以一次读一行数据的方法。 */public String myReadLine() throws IOException/* * 由于会抛出异常,这里面就不要try了。因为我们定义的是功能。 * 是给其他人使用的,要把出现的问题标识出去,让别人知道怎么处理。 */{/* * 定义一个临时容器,原BufferedReader封装的是字符数组。 * 为了演示方便,定义一个 StringBuilder容器,因为最终还是要将数据变成字符串。 */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)//只要sb的长度不为0,就会返回。如果sb的长度为0,就跳过此步。return sb.toString();return null;//到了结尾。}public void myClose() throws IOException {/* * 由于真正在操作数据的时候,用的都是FileReader里面的方法,所以,关了FileReader就ok了。 */r.close();}}public class MyBufferedReaderDemo {public static void main(String[] args) throws IOException{FileReader fr = new FileReader("buf.txt");MyBufferedReader myBuf = new MyBufferedReader(fr);String line = null;while((line=myBuf.myReadLine())!=null){System.out.println(line);}myBuf.myClose();}}/** 5 :LineNumberReader对象 * BufferedReader的子类。 *  * public class LineNumberReader extends BufferedReader, *  *   跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(), * 它们可分别用于设置和获取当前行号。  * 默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,并且可以通过 * 调用 setLineNumber(int) 更改行号。但要注意的是,setLineNumber(int) 不会实际更改 * 流中的当前位置;它只更改将由 getLineNumber() 返回的值。  *   可认为行在遇到以下符号之一时结束:换行符('\n')、回车符('\r')、回车后紧跟换行符。 *  */import java.io.*;public class LineNumberReaderDemo {public static void main(String[] args){FileReader fr = null;LineNumberReader lnr = null;BufferedWriter buw = null;try{fr = new FileReader("buf.txt");lnr = new LineNumberReader(fr);buw = new BufferedWriter(new FileWriter("BufferedWriterDemo_copy2.java"));String st = null;lnr.setLineNumber(1000);//设置起始行号。while((st = lnr.readLine())!=null){buw.write(lnr.getLineNumber()+":"+str);buw.newLine();buw.flush();}}catch(IOException e){System.out.println(e.toString());}finally{try{if(lnr!=null){lnr.close();}}catch(IOException e){System.out.println(e.toString());}if(buw != null){try{buw.close();}catch(IOException e){}}}}}/** * 练习:模拟一个带行号的缓冲区对象。 *//** 6 :LineNumberReader原理介绍和模拟 */import java.io.*;/** *  发现MyLineNumberReade类中的myReadLine()和MyBufferedReader(MyBufferedReaderDemo.java文件中) *  中的myLineReader()相同。所以可以通过继承来简化书写。 */class MyLineNumberReade extends MyBufferedReader{private int lineNumber;MyLineNumberReade(Reader r){super(r);}public String myReadLine() throws IOException { lineNumber++;return super.myReadLine(); }public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;}}/*class MyLineNumberReade{private Reader r;private int lineNumber;MyLineNumberReade(Reader r){this.r = r;}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();elsesb.append((char)ch);}if(sb.length()!=0){return sb.toString();}return null;}public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;}public void myClose() throws IOException {r.close();}}*/public class MyLineNumberReader {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("buf.txt");MyLineNumberReade mlnr = new MyLineNumberReade(fr);String line = null;mlnr.setLineNumber(10);while((line=mlnr.myReadLine())!=null){System.out.println(mlnr.getLineNumber()+":::"+line);}mlnr.myClose();}}


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

  详细请查看:http://edu.csdn.net/heima/

原创粉丝点击