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);

上面是代码的节选,使用这段代码会发现写数据时每次都成功,而读数据侧却一直没有数据输出(除非把流关掉)。经过折腾,原来这里面有几个大问题需要理解:

误以为readLine()是读取到没有数据时就返回null(因为其它read方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;因为readLine()阻塞后,System.out.println(message)这句根本就不会执行到,所以在接收端就不会有东西输出。要想执行到System.out.println(message),一个办法是发送完数据后就关掉流,这样readLine()结束阻塞状态,而能够得到正确的结果,但显然不能传一行就关一次数据流;另外一个办法是把System.out.println(message)放到while循环体内就可以。

readLine()只有在数据流发生异常或者另一端被close()掉时,才会返回null值。

如果不指定buffer大小,则readLine()使用的buffer有8192个字符。在达到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才会返回。

readLine()的实质(下面是从JDK源码摘出来的):

String readLine(boolean ignoreLF) throws IOException {

StringBuffer s = null;

int startChar;

synchronized (lock) {

ensureOpen();

boolean omitLF = ignoreLF || skipLF;

bufferLoop:

for (;;) {

if (nextChar >= nChars)

fill(); //在此读数据

if (nextChar >= nChars) { /* EOF */

if (s != null && s.length() > 0)

return s.toString();

else

return null;

}

......//其它

}

private void fill() throws IOException {

..../其它

int n;

do {

n = in.read(cb, dst, cb.length - dst); //实质

} while (n == 0);

if (n > 0) {

nChars = dst + n;

nextChar = dst;

}

}

从上面看出,readLine()是调用了read(char[] cbuf, int off, int len) 来读取数据,后面再根据"/r"或"/n"来进行数据处理。

小结,使用readLine()一定要注意:

读入的数据要注意有/r或/n或/r/n

没有数据时会阻塞,在数据流异常或断开时才会返回null

使用socket之类的数据流时,要避免使用readLine(),以免为了等待一个换行/回车符而一直阻塞

1.读取一个txt文件,方法很多种我使用了字符流来读取(为了方便)

FileReader fr = new FileReader("f:\\TestJava.Java");

BufferedReader bf = new BufferedReader(fr);

//这里进行读取

int b;

while((b=bf.read())!=-1){

System.out.println(bf.readLine());

}

发现每行的第一个字符都没有显示出来,原因呢:b=bf.read())!=-1  每次都会先读取一个字节出来,所以后面的bf.readLine())读取的就会每行少一个字节,所以,应该使用

String valueString = null;

while ((valueString=bf.readLine())!=null){

System.out.println(valueString);

}

java中br.readline_Java:java中BufferedReader的read()及readLine()方法的使用心得相关推荐

  1. 关于java中BufferedReader的read()及readLine()方法的使用心得

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

  2. java中br.readline_java中br.readLine与 br.read的用法有什么区别??

    报错?请发送错误信息 为了帮助理解我写了一个测试类,请参照 import java.io.BufferedReader; import java.io.FileNotFoundException; i ...

  3. Java基础17:Java IO流总结

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a724888/article/details/80201802 这位大侠,这是我的公众号:程序员江湖 ...

  4. java readline 实现_基于自定义BufferedReader中的read和readLine方法

    实例如下所示: package day0208; import java.io.FileReader; import java.io.IOException; /* * 自定义读取缓冲区,实现Buff ...

  5. java中readline函数_自定义BufferedReader中read和readLine方法

    BufferedReader中read和readLine方法总结 实例如下所示: package day0208; import java.io.FileReader; import java.io. ...

  6. java中输入方式Scanner和BufferedReader

    Scanner 在java.util包中,需要引入时可以用import java.util.*;或者import java.util.Scanner; 工作原理:通过new创建一个Scanner对象, ...

  7. java中br.readLine与 br.read的用法区别

    read方法功能:读取单个字符. 返回:作为一个整数(其范围从 0 到 65535 (0x00-0xffff))读入的字符,如果已到达流末尾,则返回 -1 readLine方法功能:读取一个文本行.通 ...

  8. java readline 超时_跳过Java中的BufferedReader readLine()方法

    是否有一种简单的方法可以跳过java中的readLine()方法(如果它花费的时间超过2秒)? 这是我问这个问题的背景: public void run() { boolean looping = t ...

  9. 聚合中返回source_Java 8 中的 Streams API 详解—— Streams 的背景以及 Java 8 中的使用详解...

    为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...

最新文章

  1. 手把手教你写移动端瀑布流控件布局篇
  2. java的线程管理器,QuickThread - Java线程池管理器
  3. python xlrd处理表格常用方法
  4. TensorFlow 对数据集标记的xml文件解析记录
  5. 2020 我的C++的学习之路 第八章函数
  6. Python if条件判断
  7. java事务_JAVA事务
  8. selenium, firefox, python环境搭建指南
  9. Qt4_坐标系统变换
  10. linux怎么打开rdp文件,RDP报表工具如何在Linux机器上部署?
  11. 用 cmd 查询硬盘序列号、笔记本电脑序列号、主板型号、电脑配置、WiFi 密码
  12. 使用c#制作赛尔号登录器
  13. 测试新人如何提高工作效率
  14. python数据分析18-21
  15. 反思-我们真的初老了么?
  16. 北邮通信博士带你秒懂 4G/5G 区别(附带通信发展史)
  17. 刷题集--贪吃的九头龙
  18. RunApi在发送请求的时候添加Token
  19. 笔记本电脑更改计算机驱动怎么进不去,笔记本电脑进入不了BIOS的原因与解决办法...
  20. 中国哪些云主机比较靠谱?

热门文章

  1. linux 管道文件上机总结,[转载]LINUX 管道 fifo 等总结
  2. js 获取url问号前_PHP获取指定网页的HTML代码并执行输出
  3. android 日历仿IOS,基于Android week view仿小米和iphone日历效果
  4. python随机划分数据集_Python之机器学习-sklearn生成随机数据
  5. linux fb应用例子,Linux下利用framebuffer画点的程序小例子
  6. SOCKET bind INADDR_LOOPBACK和INADDR_ANY的区别
  7. 设置最大值_变频器用远传压力表控制恒压供水参数设置
  8. python归一化 增大差异_Python逻辑回归模型原理及实际案例应用
  9. angular和JAVA实现aes、rsa加密解密,前后端交互,前端加解密和后端JAVA加解密实现
  10. 数据结构 - 线索化二叉树(线索化与遍历)