【发布时间】:2013-10-15 05:30:50
【问题描述】:
我正在使用 Java 以 Big Endian 字节顺序格式将字节数组值写入文件。现在我需要从 C++ 程序中读取该文件...
我正在写入文件的字节数组由三个字节数组组成,如下所述-
short employeeId = 32767;
long lastModifiedDate = "1379811105109L";
byte[] attributeValue = os.toByteArray();
我正在将employeeId、lastModifiedDate 和attributeValue 一起写入一个字节数组,然后我将生成的字节数组写入一个文件,然后我将使用我的 C++ 程序来检索该字节数组数据从文件然后反序列化它以从中提取employeeId、lastModifiedDate 和attributeValue。
下面是我的工作 Java 代码,它将字节数组值写入大端格式的文件:
public class ByteBufferTest {
public static void main(String[] args) {
String text = "Byte Array Test For Big Endian";
byte[] attributeValue = text.getBytes();
long lastModifiedDate = 1289811105109L;
short employeeId = 32767;
int size = 2 + 8 + 4 + attributeValue.length; // short is 2 bytes, long 8 and int 4
ByteBuffer bbuf = ByteBuffer.allocate(size);
bbuf.order(ByteOrder.BIG_ENDIAN);
bbuf.putShort(employeeId);
bbuf.putLong(lastModifiedDate);
bbuf.putInt(attributeValue.length);
bbuf.put(attributeValue);
bbuf.rewind();
// best approach is copy the internal buffer
byte[] bytesToStore = new byte[size];
bbuf.get(bytesToStore);
writeFile(bytesToStore);
}
/**
* Write the file in Java
* @param byteArray
*/
public static void writeFile(byte[] byteArray) {
try{
File file = new File("bytebuffertest");
FileOutputStream output = new FileOutputStream(file);
IOUtils.write(byteArray, output);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
现在我需要使用下面的 C++ 程序从同一个文件中检索字节数组并将其反序列化以从中提取 employeeId、lastModifiedDate 和 attributeValue。我不确定 C++ 方面的最佳方式是什么。以下是我到目前为止的代码:
int main() {
string line;
std::ifstream myfile("bytebuffertest", std::ios::binary);
if (myfile.is_open()) {
uint16_t employeeId;
uint64_t lastModifiedDate;
uint32_t attributeLength;
char buffer[8]; // sized for the biggest read we want to do
// read two bytes (will be in the wrong order)
myfile.read(buffer, 2);
// swap the bytes
std::swap(buffer[0], buffer[1]);
// only now convert bytes to an integer
employeeId = *reinterpret_cast<uint16_t*>(buffer);
cout<< employeeId <<endl;
// read eight bytes (will be in the wrong order)
myfile.read(buffer, 8);
// swap the bytes
std::swap(buffer[0], buffer[7]);
std::swap(buffer[1], buffer[6]);
std::swap(buffer[2], buffer[5]);
std::swap(buffer[3], buffer[4]);
// only now convert bytes to an integer
lastModifiedDate = *reinterpret_cast<uint64_t*>(buffer);
cout<< lastModifiedDate <<endl;
// read 4 bytes (will be in the wrong order)
myfile.read(buffer, 4);
// swap the bytes
std::swap(buffer[0], buffer[3]);
std::swap(buffer[1], buffer[2]);
// only now convert bytes to an integer
attributeLength = *reinterpret_cast<uint32_t*>(buffer);
cout<< attributeLength <<endl;
myfile.read(buffer, attributeLength);
// now I am not sure how should I get the actual attribute value here?
//close the stream:
myfile.close();
}
else
cout << "Unable to open file";
return 0;
}
我专门将存储 Java 端设置为 big-endian,这意味着我知道我猜每个字节属于哪里。那么如何在将字节移动到每个值的正确位置时对其进行编码呢?现在我将它编码为 little-endian 我猜这不是我想要的......
我在某处读到我可以在 C++ 中使用ntoh 来反序列化字节数组。不确定htons 是否会比我目前拥有的解决方案更好?..
如果是,那么我不确定如何在我当前的 C++ 代码中使用它?
任何人都可以看看 C++ 代码,看看我可以做些什么来改进它,因为我认为它看起来效率不高吗?有没有更好的方法来反序列化字节数组并在 C++ 端提取相关信息?
【问题讨论】:
标签: c++ bytebuffer endianness