我有类似的问题boost:asio文件读取。
boot::asio 是否支持异步读取功能中从文件系统读取常规文件?
我尝试了下面的代码,但它似乎不起作用。
#include <iostream>
#include <fstream>
#include <boost/asio.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
void handleRead(const boost::system::error_code& error, std::size_t bytesRead) {
if (!error) {
// Process the read data here
std::cout << "Read " << bytesRead << " bytes" << std::endl;
} else {
std::cerr << "Error: " << error.message() << std::endl;
}
}
int main() {
boost::asio::io_context ioContext;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> workGuard(ioContext.get_executor());
const char* filename = "example.txt";
// Open the file
int fileDescriptor = open(filename, O_RDONLY);
if (fileDescriptor == -1) {
std::cerr << "Failed to open file: " << filename << std::endl;
return 1;
}
// Wrap the file descriptor with a stream_descriptor
boost::asio::posix::stream_descriptor file(ioContext, fileDescriptor);
// Create a buffer to hold the file data
const std::size_t bufferSize = 1024;
std::vector<char> buffer(bufferSize);
// Read the file asynchronously
boost::asio::async_read(file, boost::asio::buffer(buffer),
boost::asio::transfer_at_least(1),
boost::bind(&handleRead, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
// Run the I/O service
ioContext.run();
return 0;
}
我可以看到我的handleRead被调用,但bytesRead始终为1024,无论文件大小如何。该文件只有几个字节的数据。
是的,可以。
您的代码已经可以工作了,请查看它Live On Coliru (简化版)
g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp
./a.out
touch example.txt; ./a.out
echo -n 'abc' >> example.txt; ./a.out
echo -n 'def' >> example.txt; ./a.out
打印
Failed to open file: example.txt
End of file: 0 bytes
Success: 3 bytes
Success: 6 bytes
请注意,最近 Asio(1.22.0 或 Boost 1.78)获得了文件支持。它还具有随机访问支持,并将在各种平台上使用更优化的接口(例如 Windows 完成端口和 Linux 上的 io_uring)。请参阅文件和管道。演示:
#define BOOST_ASIO_HAS_IO_URING 1 // on linux
#include <boost/asio.hpp>
#include <boost/asio/stream_file.hpp>
#include <iostream>
namespace asio = boost::asio;
void handleRead(boost::system::error_code ec, size_t n) {
std::cout << ec.message() << ": " << n << " bytes" << std::endl;
}
int main(int argc, char** argv) try {
asio::io_context ioc;
auto work = make_work_guard(ioc);
auto filename = argc > 1 ? argv[1] : "example.txt";
// Open the file
using asio::stream_file;
stream_file file(ioc, filename, stream_file::flags::read_only);
// Create a buffer to hold the file data
size_t bufferSize = 1024;
std::vector<char> buffer(bufferSize);
// Read the file asynchronously
async_read(file, asio::buffer(buffer), asio::transfer_at_least(1), handleRead);
// Run the I/O service
work.reset();
ioc.run();
} catch (boost::system::system_error const& se) {
std::cerr << "Error: " << se.code().message() << "\n";
}
请注意,这里的工作防护实际上是多余的,但我想展示如何更优雅地编写它,以防您有时以使其不冗余的方式移动事物。