第一部分: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();