You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:31:37