0

ビッグ エンディアン バイト オーダー形式の Java を使用して、バイト配列値をファイルに書き込んでいます。次に、C++ プログラムからそのファイルを読み取る必要があります。

私がファイルに書き込んでいるそのバイト配列は、以下で説明するように3つのバイト配列で構成されています-

short employeeId = 32767;
long lastModifiedDate = "1379811105109L";
byte[] attributeValue = os.toByteArray();

私は を書き込んemployeeIdlastModifiedDateおり、attributeValue一緒に単一のバイト配列とその結果のバイト配列をファイルに書き込んでいます。次に、そのバイト配列データをファイルから取得し、それをデシリアライズして抽出し、そこから C++ プログラムを作成しemployeeIdます。 . lastModifiedDateattributeValue

以下は、バイト配列値をビッグエンディアン形式のファイルに書き込む私の作業 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側をビッグエンディアンに設定しました。つまり、各バイトがどこに属しているかがわかります。では、バイトをすべての値の適切な位置にシフトしながら、どのようにコーディングすればよいでしょうか? 現在、リトルエンディアンとしてコーディングしていますが、これは私が望むものではないと思います...

ntoh私はバイト配列をデシリアライズするためにC++で使用できる場所を読んでいhtonsました..私が現在持っているものと比較してはるかに良い解決策になるかどうかわからない.

はいの場合、現在の C++ コードでそれを使用する方法がわかりませんか?

C++ コードを調べて、それを改善するために何ができるかを確認できますか? バイト配列を逆シリアル化し、C++ 側で関連情報を抽出するより良い方法はありますか?

4

1 に答える 1