【问题标题】:reading and writing binary files读写二进制文件
【发布时间】:2018-07-26 05:35:41
【问题描述】:

我对二进制文件有疑问。我想创建一个二进制文件,其中将有程序的版本号和颠覆号。然后,从该文件中,我想通过读取第一个 sizeof(uint16_t) 咬然后再读 sizeof(uint16_t) 咬来读取里面的内容。但我不知道该怎么做。 (我什至没有接近)

#include <iostream>
#include <fstream>
#include <stdint.h>

using namespace std;

void   saving_uint16_t(uint16_t number);
uint16_t reading_uint16_t();

int where = 0;

int main() {

    const uint16_t number_version = 2;
    cout << "Version: " << number_version << endl;
    cout << "Saving number..." << endl;
    saving_uint16_t(number_version);

    const uint16_t number_subversion = 1;
    cout << "Subversion: " << number_subversion << endl;
    cout << "Saving number..." << endl;
    saving_uint16_t(number_subversion);

    cout << "Read numbers:\nVersion: " << reading_uint16_t() << "\nSubversion: " << reading_uint16_t() << endl << endl;

    return 0;
}

void saving_uint16_t(uint16_t number) {

    ofstream data("numbers.bin",  ios::app | ios::binary);
    data.write(reinterpret_cast<char*>(&number), sizeof(uint16_t));
}

uint16_t reading_uint16_t(){

    ifstream data("numbers.bin", ios::binary);
    data.seekg(where);
    where = where + 16;
    uint16_t result;
    data.read(reinterpret_cast<char*>(&result), sizeof(uint16_t));
    return result;
}

我真的很陌生,我不知道该用什么。

输出:

Version: 3
Saving number...
Subversion: 7
Saving number...
Read numbers:
Version: 3
Subversion: 3

然后我改变了数字,我仍然得到:

Version: 2
Saving number...
Subversion: 1
Saving number...
Read numbers:
Version: 3
Subversion: 3

应该是:

Version: 2
Saving number...
Subversion: 1
Saving number...
Read numbers:
Version: 2
Subversion: 1

我想补充一点,我的目标是创建一个二进制文件,其中有两个 uint16_t 变量,然后从文件中单独读取它们。所以我可以写那个版本:(第一个uint16_t),颠覆:(第二个uint16_t)

【问题讨论】:

  • 你展示的程序,有什么问题吗?你有构建错误吗?崩溃?意外行为?出乎意料的输出?请read about how to ask good questionslearn how to debug your programs。并编辑您的问题以包含我要求的所有详细信息,以及预期和实际输出。
  • 每次调用reading int,都是从文件开头开始
  • 为了阅读,你应该打开文件一次,阅读你需要的所有内容,然后关闭它。同样,对于写入,您应该打开文件一次,写入您需要的所有内容(从头开始,没有ios:app 标志)并关闭它。如果你真的想让一个函数读取一个uint16_t,那么只需将一个对已经打开的流的引用作为参数传递给它。
  • 文件偏移量不是以位为单位的。
  • 请注意,您的 reading_uint16_t 调用可以按任何顺序发生,这是不使用全局可变状态的另一个很好的理由。

标签: c++ binaryfiles


【解决方案1】:

因此,通过查看提取 numbers.bin 中所有 uint16_ts 的函数,您的理解可能会有所提高。假设 numbers.bin 包含的所有内容都是 uint16_ts 那么你可以这样做:

ifstream data("numbers.bin", ios_base::binary | ios_base::ate); // Starting at the end of the stream for sizing
const auto count = data.tellg() / sizeof(uint16_t); // tellg will report the number of characters in the file, sizeof(uint16_t) the numberof characters required to store a uint16_t, thus the division will give us the number of uint16_ts in numbers.bin
vector<uint16_t> numbers(count); // Allocate storage for all the uint16_ts in numbers.bin

data.seekg(0U, ios_base::beg); // Move the input position indicator to the beginning of the file for reading
data.read(reinterpret_cast<char*>(numbers.data()), count * sizeof(uint16_t)); // Slurp the file into numbers

类似地,要访问 numbers.bin 的特定元素,我们需要相应地设置位置:

ifstream data("numbers.bin", ios_base::binary); // Starting at the beginning of the file
const auto where = 2U; // This offset will be 0 based
uint16_t number; // Allocate storage for the element at where

data.seekg(where * sizeof(uint16_t)); // Move the input position indicator to the specified uint16_t
data.read(reinterpret_cast<char*>(&number), sizeof(number)); // Read the element into number

Live Example

【讨论】:

    猜你喜欢
    • 2012-01-26
    • 2016-06-14
    • 2021-06-03
    • 2019-04-20
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多