繁体   English   中英

在文件中用Java编写一个Long并用C ++读取它

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM