有人可以提供使用 boost iostreams 查找、读取和写入大于 4GB 文件的示例吗

发布于 2024-08-01 21:09:04 字数 268 浏览 8 评论 0 原文

我读到 boost iostreams 据说支持 64 位半便携式方式访问大文件。 他们的常见问题解答提到64 位偏移函数 ,但没有关于如何使用它们的示例。 有人使用这个库来处理大文件吗? 打开两个文件、查找它们的中间部分并将一个文件复制到另一个文件的简单示例将非常有帮助。

谢谢。

I have read that boost iostreams supposedly supports 64 bit access to large files semi-portable way. Their FAQ mentions 64 bit offset functions, but there is no examples on how to use them. Has anyone used this library for handling large files? A simple example of opening two files, seeking to their middles, and copying one to the other would be very helpful.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌逼全场 2024-08-08 21:09:04

简短回答

只需包含

#include <boost/iostreams/seek.hpp>

并使用 seek 函数,其中

boost::iostreams::seek(device, offset, whence);

  • device 是文件、流、streambuf 或任何可转换为 seekable 的对象;
  • offsetstream_offset;
  • whenceBOOST_IOS::begBOOST_IOS::curBOOST_IOS::end

seek 的返回值是 std::streampos 类型,并且可以使用 stream_offset ://www.boost.org/doc/libs/1_42_0/libs/iostreams/doc/functions/positioning.html#position_to_offset" rel="noreferrer">position_to_offset 函数。

示例

这是一个冗长、乏味且重复的示例,它展示了如何打开两个文件、寻找偏移量 >4GB 以及如何在它们之间复制数据。

警告:此代码将创建非常大的文件(几个 GB)。 在支持稀疏文件的操作系统/文件系统上尝试此示例。 Linux 还可以; 我没有在其他系统(例如Windows)上进行测试。

/*
 * WARNING: This creates very large files (several GB)
 * unless your OS/file system supports sparse files.
 */
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/positioning.hpp>
#include <cstring>
#include <iostream>

using boost::iostreams::file_sink;
using boost::iostreams::file_source;
using boost::iostreams::position_to_offset;
using boost::iostreams::seek;
using boost::iostreams::stream_offset;

static const stream_offset GB = 1000*1000*1000;

void setup()
{
    file_sink out("file1", BOOST_IOS::binary);
    const char *greetings[] = {"Hello", "Boost", "World"};
    for (int i = 0; i < 3; i++) {
        out.write(greetings[i], 5);
        seek(out, 7*GB, BOOST_IOS::cur);
    }
}

void copy_file1_to_file2()
{
    file_source in("file1", BOOST_IOS::binary);
    file_sink out("file2", BOOST_IOS::binary);
    stream_offset off;

    off = position_to_offset(seek(in, -5, BOOST_IOS::end));
    std::cout << "in: seek " << off << std::endl;

    for (int i = 0; i < 3; i++) {
        char buf[6];
        std::memset(buf, '\0', sizeof buf);

        std::streamsize nr = in.read(buf, 5);
        std::streamsize nw = out.write(buf, 5);
        std::cout << "read: \"" << buf << "\"(" << nr << "), "
                  << "written: (" << nw << ")" << std::endl;

        off = position_to_offset(seek(in, -(7*GB + 10), BOOST_IOS::cur));
        std::cout << "in: seek " << off << std::endl;
        off = position_to_offset(seek(out, 7*GB, BOOST_IOS::cur));
        std::cout << "out: seek " << off << std::endl;
    }
}

int main()
{
    setup();
    copy_file1_to_file2();
}

Short answer

Just include

#include <boost/iostreams/seek.hpp>

and use the seek function as in

boost::iostreams::seek(device, offset, whence);

where

  • device is a file, stream, streambuf or any object convertible to seekable;
  • offset is a 64-bit offset of type stream_offset;
  • whence is BOOST_IOS::beg, BOOST_IOS::cur or BOOST_IOS::end.

The return value of seek is of type std::streampos, and it can be converted to a stream_offset using the position_to_offset function.

Example

Here is an long, tedious and repetitive example, which shows how to open two files, seek to offstets >4GB, and copying data between them.

WARNING: This code will create very large files (several GB). Try this example on an OS/file system which supports sparse files. Linux is ok; I did not test it on other systems, such as Windows.

/*
 * WARNING: This creates very large files (several GB)
 * unless your OS/file system supports sparse files.
 */
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/positioning.hpp>
#include <cstring>
#include <iostream>

using boost::iostreams::file_sink;
using boost::iostreams::file_source;
using boost::iostreams::position_to_offset;
using boost::iostreams::seek;
using boost::iostreams::stream_offset;

static const stream_offset GB = 1000*1000*1000;

void setup()
{
    file_sink out("file1", BOOST_IOS::binary);
    const char *greetings[] = {"Hello", "Boost", "World"};
    for (int i = 0; i < 3; i++) {
        out.write(greetings[i], 5);
        seek(out, 7*GB, BOOST_IOS::cur);
    }
}

void copy_file1_to_file2()
{
    file_source in("file1", BOOST_IOS::binary);
    file_sink out("file2", BOOST_IOS::binary);
    stream_offset off;

    off = position_to_offset(seek(in, -5, BOOST_IOS::end));
    std::cout << "in: seek " << off << std::endl;

    for (int i = 0; i < 3; i++) {
        char buf[6];
        std::memset(buf, '\0', sizeof buf);

        std::streamsize nr = in.read(buf, 5);
        std::streamsize nw = out.write(buf, 5);
        std::cout << "read: \"" << buf << "\"(" << nr << "), "
                  << "written: (" << nw << ")" << std::endl;

        off = position_to_offset(seek(in, -(7*GB + 10), BOOST_IOS::cur));
        std::cout << "in: seek " << off << std::endl;
        off = position_to_offset(seek(out, 7*GB, BOOST_IOS::cur));
        std::cout << "out: seek " << off << std::endl;
    }
}

int main()
{
    setup();
    copy_file1_to_file2();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文