欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android从Socket流读取文件数据,按照头标记拆分byte数组

程序员文章站 2022-07-15 11:58:23
...
 public static String readCMDFromSocket(InputStream in) {
    // 8M
    int MAX_BUFFER_BYTES = 1024 * 1024*8;
    String msg = "";
    byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];
    try {
        int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
        msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");
        // 报文总长度
        long msgLenth = 0;
        // 已经读取的长度
        long readLenth = numReadedBytes;
        if (!"".equals(msg)) {
            msgLenth = Long.valueOf(msg.substring(0, 8));
            msg = msg.substring(8, msg.length());
            while (readLenth < msgLenth) {
                // 一直读取
                int newReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
                msg += new String(tempbuffer, 0, newReadedBytes, "utf-8");
                // 直到已经读取的总长度等于总长度,不再读取
                readLenth += newReadedBytes;
            }
        }
        Log.e("TAG", "readCMDFromSocket: " + tempbuffer.length + "-----" + numReadedBytes);
        return msg;
    } catch (Exception e) {
        Log.e("TAG", Thread.currentThread().getName() + "---->" + "readFromSocket error");
        e.printStackTrace();
    }
    return null;
}

以上代码,是从Socket流读取完整数据

每次调用后台,只读取50K大小数据,防止一次性读取多,数据不完整,解析失败。

private void pollResult(BufferedOutputStream out) throws IOException {
    // 从数据库,查出后台返回的结果
    String result = pollData(context, new SQLdm().openDatabase(context), 1);
    // 初始化
    byte[] bytes = result.getBytes("utf-8");

    // 命令左补齐8位+查询的结果,例00000000256
    result = String.format("%08d", bytes.length + 8) + result;
    bytes = result.getBytes("utf-8");

    if (bytes.length > 1024 * 50) {
        // 长度超过50K,拆分
        byte[][] bytes1 = splitBytes(bytes, 1024 * 50);
        for (int i = 0; i < bytes1.length; i++) {
            out.write(bytes1[i], 0, bytes1[i].length);
        }
        // 遍历输出,再清空缓存
        out.flush();
    } else {
       // 没有超过50K,直接输出流,清空缓存
        out.write(bytes, 0, bytes.length);
        out.flush();
    }
}

工具类方法 拆分byte[]数组,每次50K

   /**
     * 拆分byte数组
     *
     * @param bytes 要拆分的数组
     * @param size  要按几个组成一份
     * @return
     */
    public byte[][] splitBytes(byte[] bytes, int size) {
        double splitLength = Double.parseDouble(size + "");
        int arrayLength = (int) Math.ceil(bytes.length / splitLength);
        byte[][] result = new byte[arrayLength][];
        int from, to;
        for (int i = 0; i < arrayLength; i++) {
            from = (int) (i * splitLength);
            to = (int) (from + splitLength);
            if (to > bytes.length)
                to = bytes.length;
            result[i] = Arrays.copyOfRange(bytes, from, to);
        }
        return result;
    }

向后台发送数据,同样左补齐8位

public static String connectSuccess() throws Exception {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("code", "00");
    jsonObject.put("message", "成功");
    // 设置发送的内容
    String outJsonData = jsonObject.toString();

    byte[] bytes = outJsonData.getBytes("utf-8");
    // 左补齐8位置,发送Json串
    outJsonData = String.format("%08d", bytes.length + 8) + outJsonData;
    return outJsonData;
}