c++ 如何重新排序此二进制文件

gcuhipw9  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(239)

我有这两个二进制文件,这是输出的java代码和C++代码在同一台机器上。问题是字节顺序似乎不同(也许是小端对大端?)。所以问题是:为什么这在同一台机器上是不同的?以及我如何以相同的字节顺序转换/查看文件以比较它们?
左边的文件是通过以下方式实现的:

std::ofstream file("binary.bin", std::ios::binary);

  for (const auto& row : vector) {
      file.write(reinterpret_cast<const char*>(row.data()), row.size() * sizeof(float));
  }

  file.close();

在Java中(右):

File file = new File(path, "/" + "binary2.bin");
 try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(byteArray);
        } catch (IOException e) {
            e.printStackTrace();
        }

谢啦,谢啦

gijlo24d

gijlo24d1#

不幸的是,没有给出那么多信息。看起来4个字节的块被颠倒了。
这可能与实现有关。C++以一种方式存储,Java以另一种方式存储。但由于我们看不到程序在写,我们只能猜测。我们也看不到文件的结构(1字节数据或2字节数据或4字节数据或8字节数据块或带填充的结构或其他)
但是,至少我们可以重新排序4字节的二进制数据块。
这并不复杂。我们打开手头的文件,读取std::vector中的所有数据,然后关闭文件。
然后我们重新打开文件进行写入,这将覆盖之前在文件中的所有内容,文件将为空。
我们迭代std::vector中的源数据,并使用算法库中的std::reverse函数反转4字节块。
最后,我们将所有数据写回文件。
我起草了一些演示函数来创建一个测试文件并显示内容。
请参阅:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <iterator>
#include <filesystem>
#include <algorithm>

const std::string testFileName{ "test.bin" };

// Simple program to write test data to a file
void writeTestFile() {
    // Open file for writing and check, if it is open
    if (std::ofstream ofs(testFileName,std::ios::binary); ofs) {
        // Write 128 4-byte blocks
        for (int i{}; i < 128; ++i)
            for (int k{ 3 }; k >= 0; --k)
                ofs << static_cast<unsigned char>(i * 4 + k);
    }
    else std::cerr << "\n*** Error. Could not open file '" << testFileName << "' for writing\n\n";
}
// Show binary file content on screen in hex
void showBinaryFile() {
    // Open file and check, if it could be opened
    if (std::ifstream ifs(testFileName, std::ios::binary); ifs) {
        std::cout << "\n\n---------------------------------------------------------------\n";
        unsigned int counterForLineBreak{};

        // Read all data from file in a loop and display it
        for (unsigned char c = ifs.get(); ifs; c = ifs.get()) {
            std::cout << std::right << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(c) << ' ';
            if (++counterForLineBreak % 16 == 0) std::cout << '\n';
        }
    } 
    else std::cerr << "\n*** Error. Could not open file '" << testFileName << "' for reading\n\n";
}
// Simply reverse 4 byte blocks of a binary file
// File size must be multiple of 4
void flip() {
    // Open file for reading and check, if it could be opened
    if (std::ifstream ifs(testFileName, std::ios::binary); ifs) {

        // Read complete file into a std::vector
        std::size_t size{ std::filesystem::file_size(testFileName) };
        std::vector<unsigned char> content(size);
        ifs.read(reinterpret_cast<char*>(content.data()), size);
        // Close the file that we just read
        ifs.close();

        // Open file again. Now for writing. Check, if it could be opened
        if (std::ofstream ofs(testFileName, std::ios::binary); ofs) {

            // Reverse 4 byte blocks in std::vector
            for (std::size_t i{}; i < size; i += 4)
                std::reverse(content.data() + i, content.data() + std::min(i + 4, size));

            // Write data back to file
            ofs.write(reinterpret_cast<char*>(content.data()), size);
        }
        else std::cerr << "\n*** Error. Could not open file '" << testFileName << "' for writing\n\n";
    }
    else std::cerr << "\n*** Error. Could not open file '" << testFileName << "' for reading\n\n";

}
// Test program
int main() {
    writeTestFile();
    showBinaryFile();
    flip();
    showBinaryFile();
}

相关问题