Java中DataInputOutputStream的readInt()与available()差异及流读取用法咨询
嘿,Janaka,我来帮你理清这两个方法的区别,再说说怎么用它们处理你给的数据流~
Java中DataInputStream的readInt()与available()区别及使用示例
一、先搞懂readInt()和available()的核心区别
这俩方法都是DataInputStream里的,但职责完全不一样,我给你掰扯清楚:
- readInt():这是个专门读取二进制int的方法,它会从流里读4个字节(因为Java的int占4字节),然后按大端字节序转换成int值。最关键的是它是阻塞式的——如果当前流里凑不够4个字节,它会一直等,直到拿到足够的字节,或者流结束抛出
EOFException。它的作用就是精准读取固定长度的int类型数据,比如数据流里的长度标识。 - available():这个方法是用来告诉你“当前流里有多少字节可以不用阻塞直接读”,返回的是一个估计值,不是绝对准的(比如网络流可能后面还有数据在传输,但当前能读的就这么多)。它不会阻塞,只是给你一个参考,而且绝对不能用它判断流是否结束——哪怕返回0,也可能只是暂时没数据,不是流关了。
二、用这俩方法处理你给的数据流
先看你给的数据流:
[{"frame_id":"48","get_person":true,"type":"get_person","sensor_type":"mjpeg","data_size":41,"engine_id":"rtface"}{"type": "GET_PEOPLE_RESP", "people": []}]
首先得明确:用DataInputStream处理这类JSON数据流,通常的约定是先传4字节的int长度(表示后续JSON的字节数),再传JSON内容——你这里JSON里的data_size:41应该就是第一个JSON的字节数,所以我们可以按这个逻辑来处理:
步骤&示例代码
import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import com.google.gson.Gson; public class JsonStreamReader { public static void main(String[] args) { // 替换成你的实际输入流(比如网络Socket的输入流、文件输入流) InputStream yourInputStream = ...; try (DataInputStream dis = new DataInputStream(yourInputStream)) { // 1. 用readInt()读取第一个JSON的长度(对应data_size:41) // 注意:这里假设数据流开头是4字节的二进制int,不是字符串"41" int firstJsonLength = dis.readInt(); // 2. 读取对应长度的字节,这里可以结合available()判断当前可用字节,但更可靠的是循环读取 byte[] firstJsonBytes = new byte[firstJsonLength]; int totalRead = 0; while (totalRead < firstJsonLength) { // 每次读取当前可用的字节,最多不超过剩余需要的数量 int currentAvailable = dis.available(); int readCount = dis.read(firstJsonBytes, totalRead, Math.min(currentAvailable, firstJsonLength - totalRead)); if (readCount == -1) { throw new IOException("数据流提前结束,没读到足够的字节"); } totalRead += readCount; } // 3. 转换成字符串并解析JSON String firstJsonStr = new String(firstJsonBytes, "UTF-8"); Gson gson = new Gson(); FrameData firstFrame = gson.fromJson(firstJsonStr, FrameData.class); System.out.println("解析出的第一个帧数据:" + firstFrame.frame_id + ",是否获取到人:" + firstFrame.get_person()); // 4. 处理第二个JSON,用available()获取剩余可用字节 int remainingBytes = dis.available(); byte[] secondJsonBytes = new byte[remainingBytes]; // readFully会阻塞直到读完所有字节,比循环读更省心 dis.readFully(secondJsonBytes); String secondJsonStr = new String(secondJsonBytes, "UTF-8"); PeopleResp peopleResp = gson.fromJson(secondJsonStr, PeopleResp.class); System.out.println("解析出的响应类型:" + peopleResp.type + ",人数:" + peopleResp.people.length); } catch (IOException e) { e.printStackTrace(); } } // 对应第一个JSON的实体类 static class FrameData { String frame_id; boolean get_person; String type; String sensor_type; int data_size; String engine_id; // 可以加getter/setter,Gson不强制要求 } // 对应第二个JSON的实体类 static class PeopleResp { String type; Object[] people; } }
注意事项
- 如果你的数据流没有开头的4字节长度标识(也就是直接传的JSON字符串),那
readInt()就不适用了——这时候应该用InputStreamReader结合BufferedReader来读字符流,DataInputStream更适合处理二进制数据。 available()只是辅助参考,不要依赖它来决定是否结束读取,比如网络流可能中途暂停传输,available()返回0,但后续还有数据,这时候用循环读取或readFully()更可靠。- 解析JSON一定要用成熟的库(比如Gson、Jackson),手动解析容易踩各种坑。
内容的提问来源于stack exchange,提问作者HWJ
相关产品推荐
相关产品推荐

