总结BufferedReader类的用法

第一部分:java中的new BufferedReader(new InputStreamReader(System.in))

对这句话的详细解释和理解:

System.in的类型可以归结为节点流、字节流、输入流;
InputStreamReader这个对象是处理流,字符流,输入流;
BufferedReader的类型是缓冲处理流、字符流、输入流。

类 InputStreamReader是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。如:GBK
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如: BufferedReader in= new BufferedReader(new InputStreamReader(System.in));

System.in是个字节流

InputStreamReader是个字符流和字节流之间的转换中介

BufferedReader是个字符流
整体意思就是用InputStreamReader这个中介把System.in这个字节流转换成字符流BufferedReader
这样输入的时候就可以不是一个一个字节读,而是一个一个字符读,再加上是个Buffer,效率会高很多。
InputStream is = System.in;//键盘输入流
InputStreamReader isr = new InputStreamReader(is);//字节流转换为字符流
BufferedReader bufr = new BufferedReader(isr);//把字符流添加到缓冲流

下面对BufferedReader的read()及readLine()方法的使用进行总结:

BufferedReader的readLine()方法是阻塞式的, 如果到达流末尾, 就返回null, 但如果client的socket末经关闭就销毁, 则会产生IO异常. 正常的方法就是使用socket.close()关闭不需要的socket.

从一个有若干行的文件中依次读取各行,处理后输出,如果用以下方法,则会出现除第一行外行首字符丢失现象

String str = null;
br=new BufferedReader(new FileReader(fileName));
do{
str = buf.readLine());
}while(br.read()!=-1);
以下用法会使每行都少首字符
while(br.read() != -1){
str = br.readLine();
}
原因就在于br.read() != -1 这判断条件上。 因为在执行这个条件的时候其实它已经读取了一个字符了,然而在这里并没有对读取出来的这个字符做处理,所以会出现少一个字符,如果你这里写的是while(br.readLine()!=null)会出现隔一行少一行!

建议使用以下方法
String str = null;
while((str = br.readLine()) != null){
//System.out.println(str);//此时str就保存了一行字符串
}

这样应该就可以无字符丢失地得到一行了

虽然写IO方面的程序不多,但BufferedReader/BufferedInputStream倒是用过好几次的,原因是:

它有一个很特别的方法:readLine(),使用起来特别方便,每次读回来的都是一行,省了很多手动拼接buffer的琐碎;
它比较高效,相对于一个字符/字节地读取、转换、返回来说,它有一个缓冲区,读满缓冲区才返回;一般情况下,都建议使用它们把其它Reader/InputStream包起来,使得读取数据更高效。
对于文件来说,经常遇到一行一行的,特别相符情景。
这次是在蓝牙开发时,使用两个蓝牙互相传数据(即一个发一个收),bluecove这个开源组件已经把数据读取都封装成InputStream了,也就相当于平时的IO读取了,很自然就使用起readLine()来了。

发数据:

BufferedWriter output = new BufferedWriter(new OutputStreamWriter(conn.openOutputStream()));   
int i = 1;  
String message = "message " + i;  
while(isRunning) {  
    output.write(message+"/n");   
    i++;  
} 

读数据:

BufferedReader input = new BufferedReader(new  InputStreamReader(m_conn.openInputStream()));  
String message = "";  
String line = null;  
while((line = m_input.readLine()) != null) {  
    message += line;  
}  
System.out.println(message);  

下面这个是一个简单读取文件内容到控制台的例子:

package com.lxk.FileTest;
 
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
/**
 * 一行一行的读取文件到内存中,然后打印输出到控制台
 */
class BufferedReaderDemo {
    public static void main(String[] args) {
        BufferedReader bufr = null;
        try {
            //创建一个字符读取流对象和文件相关联。
            FileReader fr = new FileReader("buf.txt");
            //为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
            bufr = new BufferedReader(fr);
            String line;
            try {
                while ((line = bufr.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } finally {
            if (bufr != null) {
                try {
                    bufr.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }
 
    }
 
}

下面是类似的BufferedWriter类进行解释:


public static void main(String[] args) throws Exception {
    //创建一个字符缓冲输出流对象
    BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
        
        
    //写数据
    bw.write("hello");
    bw.write("world");
    
    //刷新流
    bw.flush();
        
    //关闭资源
    bw.close();
        

猜你喜欢

转载自blog.csdn.net/StrongHelper/article/details/84697087