首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++打开文件并写入任意位置的文件

C++打开文件并写入任意位置的文件
EN

Stack Overflow用户
提问于 2016-08-22 13:31:02
回答 2查看 661关注 0票数 1

我需要打开一个现有的文件,然后写到该文件的任意位置。也位于可能大于当前文件大小的位置。

每次调用写操作时,用"ab"打开文件时,都会将位置指示符设置为文件的末尾,这样就不能工作了。

使用"w+b""wb"打开文件将导致文件多次被写入(复制?)。文件大小从0开始有几次--这需要很长时间。参见执行以下测试时发生的情况的视频(1 run):http://screencast.com/t/Uj5ymikZUYJ

代码语言:javascript
运行
复制
BOOST_AUTO_TEST_CASE(FileWriteTest_W_PLUS_B) {
    auto started = chrono::high_resolution_clock::now();

    FILE *filePointer = nullptr;
    auto tmpFilename = string("C:\\temp\\") + boost::uuids::to_string(boost::uuids::random_generator()());
    auto bufferSize = 1024 * 1024;

    unique_ptr<unsigned char[]> buffer(new unsigned char[bufferSize]);
    RAND_bytes(buffer.get(), bufferSize);

    for (long long i = 0; i < 5; i++) {
        //Open file
        int openError = fopen_s(&filePointer, tmpFilename.c_str(), "w+b");  
        if (openError != 0)
            BOOST_FAIL(string("Failed to open file ") + tmpFilename);

        auto CurrentPosition = 1024LL * 1024LL * 1024LL * i;

        //Set position to 0/1/2/3/4 GB 
        fsetpos(filePointer, &CurrentPosition);

        //Write 1 GB of data at current position
        for (int n = 0; n < 1024; n++) {
            int written = fwrite(buffer.get(), sizeof(unsigned char), bufferSize, filePointer);
            if (written != bufferSize) {
                BOOST_FAIL(string("Unable to write ") + to_string(bufferSize) + string(" to file ") + tmpFilename + string(" at position ") + to_string(CurrentPosition));
            }
        }

        //Close file
        fclose(filePointer);
    }

    auto ended = chrono::high_resolution_clock::now();
    cout << "Time :" << duration_cast<duration<double>>(ended - started).count() << " seconds";
}

因此,我的问题是:是否有任何方法打开现有文件并将其写入任意位置(也位于比当前大小更大的位置)--而不像我目前使用"wb" / "w+b"所看到的那样受到性能损失?

还是我必须使文件的最终大小--当我第一次给它写信时?(例如,Torrent客户似乎是这样做的)。

fstreams由于其糟糕的I/O性能而不是一个选项。(见writing-a-binary-file-in-c-very-fast)

EN

Stack Overflow用户

回答已采纳

发布于 2016-08-22 13:37:16

您应该以"r+b"模式打开流。"w"模式导致文件被截断。如果文件不存在,则必须首先使用"wb"创建该文件。

但是,请注意,fsetpos()可能无法在文件结束后设置当前位置。如果需要,您应该检查返回值并将文件放置到目标位置。

要使位置具有字节偏移的意义,流还必须在二进制模式下使用b打开。默认情况下,流更多地以文本形式打开,在某些系统(如Windows )中,这可能会阻止正确的偏移管理。

票数 4
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39080952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档