解决bufferedReader.readLine()读到最后发生阻塞的问题
作者:bugskiller_cn 发布时间:2022-07-15 06:05:38
bufferedReader.readLine()读到最后发生阻塞
最近在做一个imageserver,需求简化后就是使用socket响应HTTP请求从而截取所需要的数据流,写入到服务器端的文件中,从而完成客户端将图片上传到服务器。
因为从客户端得到的数据流中,我们只希望截取其中的一部分。这样就使我们无法像经常那样边读边向文件中写入,而且在流已经读到末尾时,使用bufferedInputStream.read()>0或inputStream.read()>0作为while语句结束的判断条件在使用socket获得的数据流中是无法返回-1(因为客户端是通过浏览器提交的form表单,它无法告诉服务器的socket数据已经发送结束。因此read()方法还在等待客户端发送消息产生了阻塞)。
但是我们如果不使用bufferedInputStream.read(),我们就无法得到客户端的数据流。那么我们将如何取得数据流,并避免在读取数据时发生阻塞。
我是这样解决的:
int newread = 0;
int totalread = 0;
int contentLength = Integer.parseInt(headers.get("content-length"));
byte[] bytes = new byte[contentLength];
while (totalread < contentLength) {
newread = bufferedInputStream.read(bytes, totalread, contentLength - totalread);
totalread += newread;
}
headers:自定义的map对象用来存储之前已经解析的http请求消息中Content-Length的值
这样循环读数据可以解决两个问题:
1、避免使用read()方法造成的整个程序陷入阻塞。
2、当读的数据流较大时,还可以防止read()方法不能完全读取。
这样问题即可解决,完美!
BufferedReader的readline()踩坑
刚刚踩了一个readLine()方法的小坑
本来功能没有问题,但是根据下面的代码,我的lineStr一直为Null,看来网上的挺多这种相关的问题,但是和我的问题都不一样;
这里是有问题的代码:
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// 读取结果
System.out.println("获取:"+br.readLine());//注意这里是先打印了
String lineStr = br.readLine();//然后在获取的
后面我根据看别人解释readLine方法,发现是因为readLine方法读取了一行之后,不关闭就会读取下一行,而我只需要读取一行,所以我原来的打印吧数据拿出来了,在给lineStr赋值时它去打印下一行根本没有东西,于是我把上面的打印删掉解决了这个问题
下面是修改了的:
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// 读取结果
String lineStr = br.readLine();//直接赋值
这本身可能不算问题哈,但是难为了我小半天,做个记录。以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
来源:https://blog.csdn.net/qq_23703157/article/details/78208096
猜你喜欢
- 什么是深度优先什么是深度,即向下,深度优先,即向下优先,一口气走到底,走到底发现没路再往回走。在算法实现上来讲,深度优先可以考虑是递归的代名
- 本文实例讲述了C#自定义繁体和简体字库实现中文繁体和简体之间转换的方法。分享给大家供大家参考。具体分析如下:这里使用C#自定义繁体和简体字库
- 在一般性开发中,笔者经常看到很多同学在对待java并发开发模型中只会使用一些基础的方法。比如Volatile,synchronized。像L
- C# using 三种使用方式介绍1.using指令。using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的
- 前言本文简单介绍抽象类,接口以及它们的异同点,另附简单的代码举例。一、抽象类是什么?在 Java 语言中使用 abstract class
- 在分布式系统中,配置文件散落在每个项目中,难于集中管理,抑或修改了配置需要重启才能生效。下面我们使用 Spring Cloud Config
- springboot跳转到指定页面controller的写法必须是templates下面的页面,不经过配置,无法直接跳转到public,st
- 有时候数据库文档需要整理,可是只能手动的复制粘贴,心中一万只草泥马奔腾而过。。。screw简洁好用的数据库表结构文档生成工具。1. 创建项目
- SessionSession对象用于获取与数据库的物理连接。 Session对象是重量轻,设计了一个互动是需要与数据库每次被实例化。持久化对
- 1.插入排序这个打麻将或者打扑克的很好理解, 比如有左手有一副牌1,2,4,7 ,来一张3的牌, 是不是就是手拿着这张牌从右往左插到2,4之
- 目录一、C# 多态性二、静态多态性三、函数重载四、C# 运算符重载1、运算符重载的实现2、可重载和不可重载运算符五、动态多态性前言:👻🎄学过
- 插件安装方式:新版本IDE安装方式略有不同,不一一赘述 1、Background Image Plus
- Java 中的线程有以下状态:新建状态(New):新创建的线程,还未执行。就绪状态(Runnable):执行了 start() 方法,等待运
- 面试中会经常遇到手撕代码的情况,而求TopK的是经常遇到的题目。下面我就用Java来实现。主要通过两种方法实现,快排思想以及堆排序的思想,两
- 本文主要为大家分享了MyEclipse中安装使用Maven的方法,供大家参考,具体内容如下Step1:下载mavenhttp://maven
- RunnableRunnable接口非常简单,就定义了一个方法run(), 实现Runnable接口的run方法就可以实现多线程// 函数式
- 1. 父工程构建1.1 Maven项目搭建环境版本JDK1.8Maven3.6+Maven模板maven-archetype-size删除父
- 建造者模式(Builder Pattern)主要用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则
- 类加载机制java类从被加载到JVM到卸载出JVM,整个生命周期包括:加载(Loading)、验证(Verification)、准备(Pre
- 1. JVM 运行时数据区JVM运行时数据区可以分为元空间,堆,虚拟机栈,本地方法栈,程序计数器五大块。元空间(方法区):存放类模版对象,是