接受缓冲区序列的
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
如果您阅读文档,您会发现
[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()
如何仅仅使这个同步,我会一直简化:
#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上的内核太旧,本地演示: