.pgr照片文件解析,C++与Java存储数据差别大小端模式
2023-09-27 14:26:27 时间
1. .pgr是什么?
.pgr文件是二进制的图像文件,可以用普通的文本文件打开,或者查看十六进制的文本信息;
读取需要了解~~~非常重要 !!!
- 基本数据类型的大小端存储模式
- 表头Header
详细信息可参考:http://www.powergrep.com/manual/PowerGREP.pdf
2. C++与Java存储数据差别——大小端模式
Java是大端模式,C是小端模式;
以int为类,大端模式:高位存高位,低位存地位;
小端模式:高位存地位,地位存高位
- 如 大端:ABCD 小端:DCBA
float,double存储为 符号位,指数位,小数位,更复杂一些;
3. Java读取小端模式数据示例代码
- 可以用BufferTest
- 利用移位方法
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/*************************************
* Class Name: doubleConvert
* Description:〈大小端转换〉
* @create 2020/8/19
* @since 1.0.0
************************************/
public class doubleConvert {
/**
* 向将bytes添加到另一个bytes结尾,并返回位置
*
* @param buff 目标数组
* @param pos 目标数组放置的起始位置
* @param lens 添加的长度
* @param dx 要添加的数组
* @return lens添加的长度
*/
public static int addToBuff(byte[] buff, int pos, int lens, byte[] dx) {
System.arraycopy(dx, 0, buff, pos, lens);
return lens;
}
/**
* 获得bytes的一段数据
*
* @param buff 原byte数组
* @param startPos 起始位置
* @param lenth 获取的长度
* @return 返回获得的byte数组
*/
public static byte[] getFromBuff(byte[] buff, int startPos, int lenth) {
byte[] bytes = new byte[lenth];
System.arraycopy(buff, startPos, bytes, 0, lenth);
return bytes;
}
/**
* double转byte数组,小端模式
*
* @param d
* @return
*/
public static byte[] doubleToBytes_Little(double d) {
long l = Double.doubleToLongBits(d);
byte b[] = new byte[8];
b[7] = (byte) (0xff & (l >> 56));
b[6] = (byte) (0xff & (l >> 48));
b[5] = (byte) (0xff & (l >> 40));
b[4] = (byte) (0xff & (l >> 32));
b[3] = (byte) (0xff & (l >> 24));
b[2] = (byte) (0xff & (l >> 16));
b[1] = (byte) (0xff & (l >> 8));
b[0] = (byte) (0xff & l);
return b;
}
/**
* double转byte数组,大端模式
*
* @param d
* @return
*/
public static byte[] doubleToBytes_Big(double d) {
long l = Double.doubleToLongBits(d);
byte b[] = new byte[8];
b[0] = (byte) (0xff & (l >> 56));
b[1] = (byte) (0xff & (l >> 48));
b[2] = (byte) (0xff & (l >> 40));
b[3] = (byte) (0xff & (l >> 32));
b[4] = (byte) (0xff & (l >> 24));
b[5] = (byte) (0xff & (l >> 16));
b[6] = (byte) (0xff & (l >> 8));
b[7] = (byte) (0xff & l);
return b;
}
/**
* byte数组转double
*
* @param bytes 8位byte数组
* @param littleEndian 是否是小端模式
* @return
*/
public static double bytesToDouble(byte[] bytes, boolean littleEndian) {
ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, 8);
if (littleEndian) {
// ByteBuffer.order(ByteOrder) 方法指定字节序,即大小端模式(BIG_ENDIAN/LITTLE_ENDIAN)
// ByteBuffer 默认为大端(BIG_ENDIAN)模式
buffer.order(ByteOrder.LITTLE_ENDIAN);
}
long l = buffer.getLong();
return Double.longBitsToDouble(l);
}
/**
* long转byte数组,小端模式
*
* @param l
* @return
*/
public static byte[] longToBytes_Little(long l) {
byte b[] = new byte[8];
b[7] = (byte) (0xff & (l >> 56));
b[6] = (byte) (0xff & (l >> 48));
b[5] = (byte) (0xff & (l >> 40));
b[4] = (byte) (0xff & (l >> 32));
b[3] = (byte) (0xff & (l >> 24));
b[2] = (byte) (0xff & (l >> 16));
b[1] = (byte) (0xff & (l >> 8));
b[0] = (byte) (0xff & l);
return b;
}
/**
* long转byte数组,大端模式
*
* @param l
* @return
*/
public static byte[] longToBytes_Big(long l) {
byte b[] = new byte[8];
b[0] = (byte) (0xff & (l >> 56));
b[1] = (byte) (0xff & (l >> 48));
b[2] = (byte) (0xff & (l >> 40));
b[3] = (byte) (0xff & (l >> 32));
b[4] = (byte) (0xff & (l >> 24));
b[5] = (byte) (0xff & (l >> 16));
b[6] = (byte) (0xff & (l >> 8));
b[7] = (byte) (0xff & l);
return b;
}
/**
* byte数组转long
*
* @param bytes 8位的byte数组
* @param littleEndian 是否是小端模式
* @return
* @throws Exception
*/
public static long bytesToLong(byte[] bytes, boolean littleEndian) throws Exception {
if (bytes.length != 8) {
throw new Exception("参数错误,无法解析。");
}
ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, 8);
if (littleEndian) {
// ByteBuffer.order(ByteOrder) 方法指定字节序,即大小端模式(BIG_ENDIAN/LITTLE_ENDIAN)
// ByteBuffer 默认为大端(BIG_ENDIAN)模式
buffer.order(ByteOrder.LITTLE_ENDIAN);
}
return buffer.getLong();
}
/**
* int转byte数组 ,小端
*
* @param num
* @return
*/
public static byte[] intToBytes_Little(int num) {
byte[] result = new byte[4];
result[0] = (byte) ((num >>> 0) & 0xff);
result[1] = (byte) ((num >>> 8) & 0xff);
result[2] = (byte) ((num >>> 16) & 0xff);
result[3] = (byte) ((num >>> 24) & 0xff);
return result;
}
/**
* int转byte数组 ,大端
*
* @param num
* @return
*/
public static byte[] intToBytes_Big(int num) {
byte[] result = new byte[4];
result[0] = (byte) ((num >>> 24) & 0xff);
result[1] = (byte) ((num >>> 16) & 0xff);
result[2] = (byte) ((num >>> 8) & 0xff);
result[3] = (byte) ((num >>> 0) & 0xff);
return result;
}
/**
* byte数组转int,小端
*
* @param bytes
* @return
*/
public static int bytesToInt_Little(byte[] bytes) {
int result = 0;
if (bytes.length == 4) {
int a = (bytes[0] & 0xff) << 0;
int b = (bytes[1] & 0xff) << 8;
int c = (bytes[2] & 0xff) << 16;
int d = (bytes[3] & 0xff) << 24;
result = a | b | c | d;
}
return result;
}
/**
* byte数组转int,大端
*
* @param bytes
* @return
*/
public static int bytesToInt_Big(byte[] bytes) {
int result = 0;
if (bytes.length == 4) {
int a = (bytes[0] & 0xff) << 24;
int b = (bytes[1] & 0xff) << 16;
int c = (bytes[2] & 0xff) << 8;
int d = (bytes[3] & 0xff) << 0;
result = a | b | c | d;
}
return result;
}
/**
* byte数组转十六进制
*
* @param bytes
* @return
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder buf = new StringBuilder(bytes.length * 2);
for (byte b : bytes) { // 使用String的format方法进行转换
buf.append(String.format("%02x", new Integer(b & 0xff)));
}
return buf.toString();
}
/**
* 十六进制转byte数组
*
* @param str
* @return
*/
public static byte[] hexToBytes(String str) {
if (str == null || str.trim().equals("")) {
return new byte[0];
}
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length() / 2; i++) {
String subStr = str.substring(i * 2, i * 2 + 2);
bytes[i] = (byte) Integer.parseInt(subStr, 16);
}
return bytes;
}
public static void main(String[] args) throws Exception {
int num = 100;
// 先将int 转小端的byte[], 小端的byte[] 再转回int
System.out.println("intToLittle: " + bytesToInt_Little(intToBytes_Little(num)));
// 先将int 转大端的byte[], 大端的byte[] 再转回int
System.out.println("intToBig: " + bytesToInt_Big(intToBytes_Big(num)));
long l = 9l;
System.out.println("longToLittle: " + bytesToLong(longToBytes_Little(l), true));
System.out.println("longToBig: " + bytesToLong(longToBytes_Big(l), false));
double d = 9.125d;
System.out.println("doubleToLittle: " + bytesToDouble(doubleToBytes_Little(d), true));
System.out.println("doubleToBig: " + bytesToDouble(doubleToBytes_Big(d), false));
System.out.println("doubleToLittle---Hex: " + bytesToHex(doubleToBytes_Little(d)));
System.out.println("doubleToBig---Hex: " + bytesToHex(doubleToBytes_Big(d)));
}
}
4. 效果图
结果如下:
5. 参考
相关文章
- java中string类型转换成map
- HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot-报错解决方法
- Java 对象的序列化、反序列化
- Java 数据结构
- C#,入门教程(40)——主流编程语言C,C++,C#,Java, Go,Python的对比与建议
- Plug memory leaks in enterprise Java applications
- C++和Java函数传递数组参数比较
- 第70节:Java中xml和tomcat
- 基于Java(SSM)+MySQL的二手书籍交易系统【100010084】
- java sleep()和wait()的区别
- Java学习小记-基本数据类型&类型转换
- c++ 与 java 中的 继承
- 判断大小端的方法(java和c++)
- C++, Java和C#的编译过程解析
- 【华为OD机试真题 java、c++、python、JsNode】查找重复代码(100%通过+复盘思路)
- 【华为OD机试真题 java、python、c++、JsNode】服务中心选址、服务器最佳位置【2022 Q4 200分】
- 【华为OD机试真题 java、python、c++】获取最大软件版本号(复盘思路)
- 【华为OD机试真题 java、python、c++】字符串解密(100%通过+复盘思路)
- 【华为OD机试真题 java、python、c++】荒地电站建设【2022 Q4 100分】(100%通过+复盘思路)
- 【华为OD机试真题 java、python、c++、JsNode】士兵过河||、士兵过河(100%通过+复盘思路)
- 【华为OD机试真题 java、python、c++】获得完美走位、完美走位(100%通过+复盘思路)
- 2022年7月11日热点分享:TIOBE 7月榜单 Python、C、Java、C++霸榜前四|Java学习,必读《Java核心技术》
- Java与C/C++的比较(转)
- Java中绝对路径和相对路径的总结
- java面向对象编程——总结
- C++和Java中枚举enum的用法
- C++ 'dynamic_cast' and Java 'instanceof' 使用对比