java中字符流缓冲区的作用是什么

本篇文章为大家展示了java中字符流缓冲区的作用是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

1. 为什么要缓冲区?

程序频繁地操作一个资源(如文件),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域中,以后直接从此区域中读取数据即可,因为读内存速度比较快,这样提高性能。在IO中引入缓冲区,主要是提高流的读写效率。

2. 缓冲技术的原理?

总的来说,缓冲区就是内存里的一块区域,把数据先存内存里,然后一次性写入,类似数据库的批量操作,这样效率比较高

3. BufferedWriter类

①. 定义

public class BufferedWriter extends Writer

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

②. 常用的方法:

// 关闭此流,但要先刷新它,实际上调用了Writer类的close方法 
public void close() throws IOException 
// 刷新该流的缓冲 
public void flush() throws IOException 
// 写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义 
public void newLine() throws IOException 
// 写入字符数组的某一部分 
public void write(char[] cbuf, int off, int len) throws IOException 
// 写入单个字符 
public void write(int c) throws IOException

4. BufferedReader类

①.定义:

public class BufferedReader extends Reader

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

②. 常用的方法:

// 关闭该流并释放与之关联的所有资源 
public void close() throws IOException 
// 读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行 
public String readLine() throws IOException 
// 将字符读入数组的某一部分 
public int read(char[] cbuf, int off, int len) throws IOException 
// 读取单个字符 
public int read() throws IOException

范例:通过缓冲区复制一个文本文件

File source = new File("Demo.txt"); 
if (!source.exists()) { 
  return; 
} 
BufferedWriter bufferedWriter = null; 
BufferedReader bufferedReader = null; 
try { 
  bufferedReader = new BufferedReader(new FileReader(source)); 
  bufferedWriter = new BufferedWriter(new FileWriter("Demo_copy.txt")); 
  String line = null; 
  while ((line = bufferedReader.readLine()) != null) { 
    bufferedWriter.write(line); 
    bufferedWriter.newLine();  // 换行 
    bufferedWriter.flush();   //将缓冲区数据刷到指定文件中 
  } 
} catch (Exception e) { 
  throw new RuntimeException("文件复制失败!"); 
} finally { 
  // 关闭 bufferedWriter 和 bufferedReader 
}

5.缓冲区原理图解

java中字符流缓冲区的作用是什么

6.根据原理图,自定义缓冲类

 public class MyBufferedRead extends Reader{ 
  /** 
   * 缓冲区在定义时被缓冲的流对象 
   */ 
  private Reader read; 
 
  private char[] buffer = new char[1024]; 
  // 用于记录存储到缓冲区中字符个数的变量 
  private int count = 0; 
  // 用于操作数据中元素的角标 
  private int pos = 0; 
 
  public MyBufferedRead(Reader read) { 
    this.read = read; 
  } 
 
  /** 
   * 定义一个读取方法,从缓冲区中读取一个字符 
   */ 
  public int myRead() throws IOException { 
    // 读取一批数据到缓冲数据buffer中 
    if (count == 0) { 
      count = read.read(); 
      pos = 0; 
    } 
 
    if (count < 0) 
      return -1; 
 
    char ch = buffer[pos]; 
    pos++; 
    count--; 
    return ch; 
  } 
 
  /** 
   * 定义一个读取一行的方法 
   */ 
  public String myReadLine() throws IOException { 
    StringBuilder stringBuilder = new StringBuilder(); 
    int ch = 0; 
    while ((ch = read.read()) != -1) { 
      // 如果遇到此字符,则继续 
      if (ch == '\r') { 
        continue; 
      } 
      // 如果遇到此字符,表示该行读取结束 
      if (ch == '\n') { 
        return stringBuilder.toString(); 
      } 
      // 将该行的字符添加到容器 
      stringBuilder.append((char) ch); 
    } 
    // 如果读取结束,容器中还有字符,则返回元素 
    if (stringBuilder.length() != 0) { 
      return stringBuilder.toString(); 
    } 
    return null; 
 
  } 
 
  /** 
   * 关闭缓冲区 
   */ 
  public void myClose() throws IOException { 
    read.close(); 
  } 
 
  @Override 
  public int read(char[] cbuf, int off, int len) throws IOException { 
    return 0; 
  } 
 
  @Override 
  public void close() throws IOException { 
  } 
}

测试自定义缓冲类

public class MyBufferedReadDemo { 
  /** 
   * BufferedReader 方式的read方法 
   */ 
  @Test 
  public void bufferedDemo() throws IOException{ 
    FileReader fileReader = new FileReader("JAVA专业术语集.txt"); 
    BufferedReader bufferedReader = new BufferedReader(fileReader); 
    int ch = 0; 
    while ((ch = bufferedReader.read()) != -1) { 
      System.out.print((char) ch); 
    } 
    // 关闭 bufferedReader 
    bufferedReader.close(); 
  } 
   
  /** 
   * 自定义MyBufferedRead类的myRead方法 
   */ 
  @Test 
  public void myBufferedDemo() throws IOException{ 
    FileReader fileReader = new FileReader("JAVA专业术语集.txt"); 
    MyBufferedRead myBufferedRead = new MyBufferedRead(fileReader); 
    int ch = 0; 
    while ((ch = myBufferedRead.myRead()) != -1) { 
      System.out.print((char) ch); 
    } 
    myBufferedRead.myClose(); 
  } 
   
  /** 
   * BufferedReader 方式的readLine方法 
   */ 
  @Test 
  public void readLineDemo() throws IOException{ 
  FileReader fileReader = new FileReader("JAVA专业术语集.txt"); 
    BufferedReader bufferedReader = new BufferedReader(fileReader); 
    String line = null; 
    while ((line = bufferedReader.readLine()) != null) { 
      System.out.println(line); 
    } 
    bufferedReader.close();    
  } 
   
  /** 
   * 自定义MyBufferedRead类的myReadLine方法 
   */ 
  @Test 
  public void myReadLineDemo() throws IOException{ 
    FileReader fileReader = new FileReader("JAVA专业术语集.txt"); 
    MyBufferedRead myBufferedRead = new MyBufferedRead(fileReader); 
    String line = null; 
    while ((line = myBufferedRead.myReadLine()) != null) { 
      System.out.println(line); 
    } 
    myBufferedRead.myClose();   
  } 
}

①问题:上面有一个范例------缓冲区复制一个文本文件,怎么让复制后每行带有行标?
回答:

要实现此功能,最方便的是使用LineNumberReader,下面我们看下这个类

此类的定义:

public class LineNumberReaderextends BufferedReader

跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。
实现上面功能程序代码如下:

FileReader fileReader = new FileReader("tempFile\\demo.java"); 
LineNumberReader lineNumberReader = new LineNumberReader(fileReader); 
String line = null; 
// 设置开始行号 
lineNumberReader.setLineNumber(10); 
while ((line = lineNumberReader.readLine()) != null) { 
  System.out.println(lineNumberReader.getLineNumber() + "\t" + line); 
} 
lineNumberReader.close();

上述内容就是java中字符流缓冲区的作用是什么,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。