![](/img/trans.png)
[英]IO : Writing and reading to the same text file from a C++ program and from another Java program simultaneously?
[英]Writing a Long from Java in a file and reading it in C++
我想创建一个包含8个字节的文件,表示无符号长号。 该文件使用Java创建,然后由C ++读取。 这就是Java创建文件的方式:
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
public class Writer {
public static void main(String[] args) throws Exception {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(12345);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
stream.write(buffer.array());
try (FileOutputStream outputStream = new FileOutputStream("myFile")) {
outputStream.write(stream.toByteArray());
}
}
}
这就是C ++读取它的方式:
#include <iostream>
#include <vector>
#include <fstream>
#include <stdio.h>
using namespace std;
// I use this to get each byte from a file
static std::vector<char> ReadAllBytes(char const* filename) {
std::ifstream ifs(filename, ios::binary|ios::ate);
std::ifstream::pos_type pos = ifs.tellg();
std::vector<char> result(pos);
ifs.seekg(0, ios::beg);
ifs.read(&result[0], pos);
return result;
}
int main (int argc, char* argv[]) {
std::vector<char> bytes = ReadAllBytes("myFile");
std::vector<char>::iterator it = bytes.begin();
char longBytes[8];
std::copy(&(*it), &(*it) + 8, longBytes);
unsigned long value = *((unsigned long*)longBytes);
std::cout << "Size: " << value;
}
预期产量为12345
,但我获得4120793659044003840
。
我不确定我是否在Java或C ++中做错了。 或两者。 我该怎么办?
Java在“网络顺序”中写得很long
,这是一个大端。 C ++以硬件顺序读取,在您的情况下是小端。
但是,这并不意味着您的C ++程序应该翻转转换的字节,因为在这种情况下,它会在具有大端序的硬件上失败。
C提供了一组特殊功能,用于平台无关的数据与网络顺序之间的转换。 您需要使用htonll
函数,它将网络顺序中的八个字节转换为您的硬件订单。
Java写的是以big endian编码的long
字节,保证。
C ++读取字节,在您的机器上(假设为Intel x86),它们以小端解释为整数。 (摩托罗拉68k和其他人的大端。)
您的问题的一个解决方案是以可移植的方式手动重建C ++中的整数:
uint64_t value =
(uint64_t)(b[0] & 0xFF) << 56 |
(uint64_t)(b[1] & 0xFF) << 48 |
(uint64_t)(b[2] & 0xFF) << 40 |
(uint64_t)(b[3] & 0xFF) << 32 |
(uint64_t)(b[4] & 0xFF) << 24 |
(uint64_t)(b[5] & 0xFF) << 16 |
(uint64_t)(b[6] & 0xFF) << 8 |
(uint64_t)(b[7] & 0xFF) << 0;
附注:您的Java代码可以简化:
DataOutputStream out = new DataOutputStream(new FileOutputStream("myFile"));
try {
out.writeLong(12345); // 8 bytes in big endian
} finally {
out.close();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.