C++ boost asio Windows file handle async_read_until infinite loop - no eof

后端 未结 3 669
轮回少年
轮回少年 2021-02-07 23:00

I\'m using boost 1.50 with VS2010, reading using a Windows file HANDLE (which seems to be relatively uncommon compared to asio use with sockets).

Probl

3条回答
  •  無奈伤痛
    2021-02-07 23:48

    One option is to fseek() the file to the next position before the user's ReadHandler is called. Then async_read_some() can be implemented as async_read_at(ftell()).

    The AsyncReader can use ReadUntilHandle instead of the stream_handle:

    class ReadUntilHandle : public boost::asio::windows::random_access_handle
    {
      public:
        ReadUntilHandle(boost::asio::io_service& ios, HANDLE handle)
          : boost::asio::windows::random_access_handle(ios, handle)
        {}
    
        template 
        void async_read_some(const MutableBufferSequence& buffers, Handler& handler)
        {
          LARGE_INTEGER offset;
          offset.QuadPart = 0;
          if (::SetFilePointerEx(native_handle(), offset, &offset, FILE_CURRENT)) {
            async_read_some_at(offset.QuadPart, buffers,
                               std::bind(&on_read_complete, handler,
                                         native_handle(), std::ref(get_io_service()),
                                         std::placeholders::_1, std::placeholders::_2));
          } else {
            boost::system::error_code error(::GetLastError(), boost::asio::error::get_system_category());
            get_io_service().post(boost::asio::detail::bind_handler(handler, error, 0));
          }
        }
      private:
        template  static void
        on_read_complete(Handler& handler, HANDLE native_handle, boost::asio::io_service& ios,
                       boost::system::error_code error, std::size_t length)
        {
          if (0 != length) { // update file position
            LARGE_INTEGER offset;
            offset.QuadPart = length;
            if (!::SetFilePointerEx(native_handle, offset, NULL, FILE_CURRENT) && !error) {
              error.assign(::GetLastError(),  boost::asio::error::get_system_category());
            }
          }
          ios.dispatch(boost::asio::detail::bind_handler(handler, error, length));
        }
    };
    

提交回复
热议问题