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

Java如何从二进制文件读取多字节数据到整数/整数集合?

解决方案

首先,你的代码存在几个核心问题:

  • 仅读取单个字节左移8位,未组合第二个字节,无法得到完整的2字节质数
  • 循环条件错误:read()返回-1时左移8位后变为0xFFFFFF00,不等于-1,导致循环无法终止
  • 未区分文件中1字节、2字节、4字节的分段存储结构

以下是正确的实现代码,按文件分段读取并组合多字节为整数:

import java.io.*;
import java.util.ArrayList;

public class PrimeReader {
    public static void main(String[] args) throws IOException {
        readPrimes();
    }

    public static void readPrimes() throws IOException {
        ArrayList<Integer> primesFromFile = new ArrayList<>();
        FileInputStream fileStream = new FileInputStream("S28006Set1.bin");
        // 用PushbackInputStream支持字节回退,处理分段切换
        PushbackInputStream inputStream = new PushbackInputStream(fileStream);

        // 第一段:读取1字节质数(2-251)
        int currentByte;
        while ((currentByte = inputStream.read()) != -1) {
            int prime = currentByte & 0xFF; // 转换为无符号1字节整数
            // 超过251则进入第二段,将当前字节放回流中
            if (prime > 251) {
                inputStream.unread(currentByte);
                break;
            }
            primesFromFile.add(prime);
        }

        // 第二段:读取2字节质数(257-65535)
        while (true) {
            int highByte = inputStream.read();
            if (highByte == -1) break;
            int lowByte = inputStream.read();
            if (lowByte == -1) break; // 文件意外截断

            int prime = ((highByte & 0xFF) << 8) | (lowByte & 0xFF);
            // 超过65535则进入第三段,放回两个字节
            if (prime > 65535) {
                inputStream.unread(lowByte);
                inputStream.unread(highByte);
                break;
            }
            primesFromFile.add(prime);
        }

        // 第三段:读取4字节质数(>65535)
        while (true) {
            int b1 = inputStream.read();
            if (b1 == -1) break;
            int b2 = inputStream.read();
            if (b2 == -1) break;
            int b3 = inputStream.read();
            if (b3 == -1) break;
            int b4 = inputStream.read();
            if (b4 == -1) break;

            int prime = ((b1 & 0xFF) << 24) | ((b2 & 0xFF) << 16) |
                        ((b3 & 0xFF) << 8) | (b4 & 0xFF);
            primesFromFile.add(prime);
        }

        inputStream.close();
        fileStream.close();

        // 可选:打印读取结果验证
        for (int p : primesFromFile) {
            System.out.println(p);
        }
    }
}

关键说明:

  1. 无符号转换:Java的byte是有符号类型,读取后用& 0xFF转换为无符号整数,避免像0xFB(251)被解析为-5的问题。
  2. 分段切换:使用PushbackInputStream将不属于当前段的字节放回流中,确保后续分段能正确读取。
  3. 多字节组合:
    • 2字节质数:高字节左移8位,与低字节按位或,得到完整的16位无符号整数
    • 4字节质数:依次将四个字节按位左移后组合,得到32位整数
  4. 字节序适配:上述代码假设文件采用大端序(高字节在前),如果文件是小端序(低字节在前),需要调整组合顺序,例如2字节质数改为((lowByte & 0xFF) << 8) | (highByte & 0xFF)。

内容的提问来源于stack exchange,提问作者treplejigbart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:53:23