按偏移量读取文件,并打印16进制内容
在 Java 中,你可以使用 RandomAccessFile 或 FileInputStream 来从指定偏移量(offset)读取指定长度的字节数据。以下是两种实现方式:
%02X 格式化输出16进制内容:https://www.cnblogs.com/vipsoft/p/16458095.html
MappedByteBuffer: https://www.cnblogs.com/vipsoft/p/16458161.html
方法 1:使用 RandomAccessFile(推荐)
RandomAccessFile 可以直接跳转到文件的指定位置进行读取,适合随机访问文件。
import java.io.IOException;
import java.io.RandomAccessFile;
public class ReadFileFromOffset {
public static void main(String[] args) {
String filePath = "your_file.bin"; // 替换为你的文件路径
int offset = 10; // 起始偏移量
int length = 2; // 要读取的字节数
try (RandomAccessFile raf = new RandomAccessFile(filePath, "r")) {
// 跳转到指定偏移量
raf.seek(offset);
// 读取指定长度的字节
byte[] buffer = new byte[length];
int bytesRead = raf.read(buffer);
if (bytesRead != length) {
System.err.println("未能读取足够字节,可能已到文件末尾");
} else {
System.out.println("读取的字节数据: " + bytesToHex(buffer));
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 辅助方法:将字节数组转为十六进制字符串(方便查看)
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
}
方法 2:使用 FileInputStream
FileInputStream 也可以读取指定偏移量的数据,但需要手动跳过前面的字节。
import java.io.FileInputStream;
import java.io.IOException;
public class ReadFileFromOffsetWithStream {
public static void main(String[] args) {
String filePath = "your_file.bin"; // 替换为你的文件路径
int offset = 10; // 起始偏移量
int length = 2; // 要读取的字节数
try (FileInputStream fis = new FileInputStream(filePath)) {
// 跳过 offset 之前的字节
long skipped = fis.skip(offset);
if (skipped != offset) {
System.err.println("无法跳过足够字节,可能文件太小");
return;
}
// 读取指定长度的字节
byte[] buffer = new byte[length];
int bytesRead = fis.read(buffer);
if (bytesRead != length) {
System.err.println("未能读取足够字节,可能已到文件末尾");
} else {
System.out.println("读取的字节数据: " + bytesToHex(buffer));
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 辅助方法:将字节数组转为十六进制字符串
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
}
关键点说明
-
RandomAccessFilevsFileInputStream:RandomAccessFile更适合随机访问(如频繁跳转偏移量)。FileInputStream适用于顺序读取,但也可以手动skip()到指定位置。
-
seek(offset)和skip(offset):RandomAccessFile.seek(offset)直接定位到offset。FileInputStream.skip(offset)跳过offset字节,但可能受流限制(如网络流可能无法跳过)。
-
字节读取:
read(byte[])返回实际读取的字节数,可能小于请求的长度(如文件末尾)。
-
异常处理:
- 需处理
IOException(如文件不存在或权限问题)。
- 需处理
-
字节转十六进制:
- 示例代码提供了
bytesToHex()方法方便查看字节数据(如1A 2B)。
- 示例代码提供了
输出示例
如果文件 your_file.bin 在 offset=10 处的 2 个字节是 0x41 和 0x42(即 ASCII 字符 A 和 B),输出:
读取的字节数据: 41 42
适用场景
- 读取二进制文件(如
.bin、.dat)。 - 解析文件头、特定偏移量的数据(如文件格式解析)。
- 网络协议解析(如从固定位置读取字段)。
如果需要更复杂的文件操作(如内存映射),可以考虑 java.nio 的 FileChannel 和 MappedByteBuffer。
本文来自博客园,作者:VipSoft 转载请注明原文链接:https://www.cnblogs.com/vipsoft/p/18854896
浙公网安备 33010602011771号