C++ std::ofstream - 移动输出指针

4
我正在将一些数据写入文件。偶尔,我想从内存中写入一块数据,然后将put指针沿着1、2或3个字节移动,以保持4个字节的数据边界格式。
我可以创建一个包含零的新数据块并写入该块,但这似乎是不必要和笨拙的。如何移动put指针1、2或3个字节?
我不确定如何做到这一点,因为如果我调用seekp(),那么我肯定会将指针移出当前文件大小吧? 而如果我使用ofstream.write(),它是否会正确处理?即:它会在写入数据时以某种方式调整文件大小吗?

我非常确定除了直接编写代码之外,没有其他的方法可以实现它。这就是流类的工作方式。 - MicroVirus
2个回答

1

我假设你正在做类似的事情,只不过你想写入4个字节的数据并进行一些填充。

#include <fstream>

using namespace std;

struct data
{
    char first;
    char second;
};

int _tmain(int argc, _TCHAR* argv[])
{
    ofstream outFile;
    data data1;
    data data2;

    data1.first = 'a';
    data1.second = 'b';
    data2.first = 'c';
    data2.second = 'd';

    outFile.open("somefile.dat");

    outFile.write(reinterpret_cast<char*>(&data1), sizeof(data));
    outFile.write(reinterpret_cast<char*>(&data2), sizeof(data));

    outFile.close();

    return 0;
}

一种选择是将结构体简单地设为4个字节。这可能会有一个缺点,因为它可能会增加内存占用。
使用seekp可能不是一个好的选择,我试过了,它有些起作用但并不完全。
    outFile.write(reinterpret_cast<char*>(&data1), sizeof(data));
    outFile.seekp(2, ios_base::cur);
    outFile.write(reinterpret_cast<char*>(&data2), sizeof(data));
    outFile.seekp(2, ios_base::cur);

这样做确实成功在data1后添加了填充,但是并没有在data2后添加。将指针移动到结尾并不是一个好主意,因为它不会改变文件大小。我尝试在seekp之后写入0字节,但这也没有起作用。
说实话,我会实现一个辅助函数来提供此功能。这种方式更加清晰。下面是一个简单的示例:
#include <fstream>

using namespace std;

struct data
{
    char first;
    char second;
};

void WriteWithPadding(ofstream* outFile, data d, int width);

int _tmain(int argc, _TCHAR* argv[])
{
    ofstream* outFile = new ofstream();
    data data1;
    data data2;

    data1.first = 'a';
    data1.second = 'b';
    data2.first = 'c';
    data2.second = 'd';

    outFile->open("somefile.dat");

    WriteWithPadding(outFile, data1, 4);
    WriteWithPadding(outFile, data1, 4);

    outFile->close();
    delete outFile;

    return 0;
}

void WriteWithPadding(ofstream* outFile, data d, int width)
{
    if (sizeof(d) > width)
        throw;

    width = width - sizeof(d); // width is now amount of padding required
    outFile->write(reinterpret_cast<char*>(&d), sizeof(data));

    // Add Padding
    for (int i = 0; i < width; i++)
    {
        outFile->put(0);
    }
}

很棒的第一篇帖子!欢迎来到StackOverflow。 - MicroVirus

0

只是为了严谨起见,我假设您已经使用ios::binary打开了文件,因为如果没有这样做,您将会遇到问题。

写入文件时,文件的大小仅取决于您写入文件的字节数。因此,如果您向文件中写入三个字节,则会得到一个三个字节大小的文件。

为了保持四个字节的分辨率,您必须确保每次写入四个字节--如果您写入一个三个字节的对象,请再写入一个附加字节(零?)以使其达到四个字节。

希望这可以帮助您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接