c++ 在cpp中使用boost::asio以非阻塞异步方式阅读文件内容

eufgjt7s  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(129)

我有类似的问题boost:asio file read
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的形式出现,而与文件大小无关。该文件只有几个字节的数据。

lc8prwob

lc8prwob1#

你可以的
你的代码已经工作了,看看它**Live On Coliru (simplified)**

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

请注意,最近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";
}

相关问题