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); } } }
关键说明:
- 无符号转换:Java的
byte是有符号类型,读取后用& 0xFF转换为无符号整数,避免像0xFB(251)被解析为-5的问题。 - 分段切换:使用
PushbackInputStream将不属于当前段的字节放回流中,确保后续分段能正确读取。 - 多字节组合:
- 2字节质数:高字节左移8位,与低字节按位或,得到完整的16位无符号整数
- 4字节质数:依次将四个字节按位左移后组合,得到32位整数
- 字节序适配:上述代码假设文件采用大端序(高字节在前),如果文件是小端序(低字节在前),需要调整组合顺序,例如2字节质数改为
((lowByte & 0xFF) << 8) | (highByte & 0xFF)。
内容的提问来源于stack exchange,提问作者treplejigbart
相关产品推荐
相关产品推荐

