如何使用asio::stream_file::async_write_some输出多行?

问题描述 投票:0回答:1

接受缓冲区序列的

asio::stream_file::async_write_some
函数存在重载。但就我而言(请参阅下面的代码),它仅输出第一个缓冲区的内容,现在我无法弄清楚我做错了什么。当然,可以编写输出第一个缓冲区的代码并注册输出第二个缓冲区的回调(并注册输出第三个缓冲区的回调,依此类推)。但我希望有更简单的解决方案?

#include <iostream>
#include <string>
#include <vector>

#include <boost/asio.hpp>
#include <boost/asio/stream_file.hpp>

namespace asio = boost::asio;

...

    const std::vector<std::string> lines{
        "first line\n", 
        "second line\n", 
        "third line\n"
    };
    std::vector<asio::const_buffer> buffers;
    buffers.reserve(lines.size());
    for (const auto& line : lines) {
        buffers.push_back(asio::buffer(line.data(), line.size()));
    }

    asio::io_context ctx;
    const char* output_path = R"(C:\Users\MyUsername\workspace\temp\lines.txt)";
    asio::stream_file stream(ctx);
    stream.open(
        output_path,
        asio::stream_file::write_only|asio::stream_file::create
    );
    stream.async_write_some(
        buffers, 
        [](boost::system::error_code e, size_t n) {
            if (e != boost::system::errc::success) {
                std::cerr << "error, ec=" << e << " size=" << n << std::endl;
            }
        }
    );
    ctx.run();

程序结束后,

lines.txt
的内容为
first line\n

操作系统:Windows 10,Boost.ASIO 版本:103002,Visual Studio Community 版本:17.11.4

c++ asynchronous boost-asio asio
1个回答
0
投票

如果您阅读文档,您会发现

[async_]write_some
不是您要找的东西。

而是使用组合写入操作之一,如

[async_]write
https://www.boost.org/doc/libs/1_87_0/doc/html/boost_asio/reference/async_write.html

喜欢:

template <typename Range = std::vector<std::string>> void foo(Range const& lines) {
    static constexpr auto to_buffer = [](auto const& s) { return asio::buffer(s); };

    asio::io_context ctx;
    const char* output_path = R"(C:\Users\MyUsername\workspace\temp\lines.txt)";
    asio::stream_file s(ctx, output_path, asio::stream_file::write_only | asio::stream_file::create);

    async_write(s, lines | transform(to_buffer), [](auto ec, size_t n) {
        std::cerr << "completed: " << ec.message() << " n=" << n << std::endl;
    });

    ctx.run();
}

看到使用阻塞

ctx.run()
如何仅仅使这个同步,我会一直简化:

住在Coliru

#include <boost/asio.hpp>
#include <boost/asio/stream_file.hpp>
#include <filesystem>
#include <ranges>
namespace asio = boost::asio;
using std::filesystem::path;
using std::ranges::views::transform;

static constexpr auto to_buffer = [](auto const& s) constexpr { return asio::buffer(s); };

size_t foo(path const& p, std::vector<std::string> const& lines) {
    asio::stream_file s(asio::system_executor{}, p,
                        asio::stream_file::write_only | asio::stream_file::create);

    return write(s, lines | transform(to_buffer));
}

#include <format>
int main() {
    foo("three.txt", {"first line\n", "second line\n", "third line\n"});

    auto lines = std::views::iota(1, 10'001) | //
        transform([](int i) { return std::format("line {}\n", i); });
    foo("1000.txt", std::vector(lines.begin(), lines.end()));
}

由于Coliru上的内核太旧,本地演示:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.