嘿,我试图使用CEPH来存储一些数据,但是有一个问题,就是我写给CEPH并通过librados ++从CEPH读取的内容是不相同的。

所以我有一个简单的例子:

#include <iostream>
#include <string>
#include <rados/librados.hpp>

int main(int argc, const char **argv)
{

    int ret = 0;

    /* Declare the cluster handle and required variables. */
    librados::Rados cluster;
    char cluster_name[] = "ceph";
    char user_name[] = "client.admin";
    uint64_t flags = 0;

    /* Initialize the cluster handle with the "ceph" cluster name and "client.admin" user */
    {
        ret = cluster.init2(user_name, cluster_name, flags);
        if (ret < 0)
        {
            std::cerr << "Couldn't initialize the cluster handle! error " << ret << std::endl;
            return EXIT_FAILURE;
        }
        else
        {
            std::cout << "Created a cluster handle." << std::endl;
        }
    }

    /* Read a Ceph configuration file to configure the cluster handle. */
    {
        ret = cluster.conf_read_file("/etc/ceph/ceph.conf");
        if (ret < 0)
        {
            std::cerr << "Couldn't read the Ceph configuration file! error " << ret << std::endl;
            return EXIT_FAILURE;
        }
        else
        {
            std::cout << "Read the Ceph configuration file." << std::endl;
        }
    }

    /* Read command line arguments */
    {
        ret = cluster.conf_parse_argv(argc, argv);
        if (ret < 0)
        {
            std::cerr << "Couldn't parse command line options! error " << ret << std::endl;
            return EXIT_FAILURE;
        }
        else
        {
            std::cout << "Parsed command line options." << std::endl;
        }
    }

    /* Connect to the cluster */
    {
        ret = cluster.connect();
        if (ret < 0)
        {
            std::cerr << "Couldn't connect to cluster! error " << ret
                    << std::endl;
            return EXIT_FAILURE;
        }
        else
        {
            std::cout << "Connected to the cluster." << std::endl;
        }
    }

    /* Continued from previous C++ example, where cluster handle and
     * connection are established. First declare an I/O Context.
     */

    librados::IoCtx io_ctx;
    const char *pool_name = "data";

    {
        ret = cluster.ioctx_create(pool_name, io_ctx);
        if (ret < 0)
        {
            std::cerr << "Couldn't set up ioctx! error " << ret << std::endl;
            exit(EXIT_FAILURE);
        }
        else
        {
            std::cout << "Created an ioctx for the pool." << std::endl;
        }

        librados::bufferlist bl;
        std::string hw = "hello world!";
        bl.append(hw.c_str());

        ret = io_ctx.write_full("hw", bl);

        librados::bufferlist rl;
        int read_len = hw.size();
        librados::AioCompletion* rc = librados::Rados::aio_create_completion();
        ret = io_ctx.aio_read("hw", rc, &rl, read_len, 0);
        rc->wait_for_complete();

        ret = rc->get_return_value();

        if (!(ret < 0))
        {
            auto out = std::string(rl.c_str());
            std::cout << out << std::endl;
        }
        else
        {
            std::cout << "da <expletive deleted>?" << std::endl;
        }

    }

    return 0;
}


如何多次运行程序,每次都会得到hello world!,但是由于某种原因,有时我会将rmz附加到字符串中,所以我一无所知对这个。

我试过用std::vector<uint8_t>到字符串,也返回,结果相同。这就是我最初发现问题的方式。

我正在为C ++使用最新的librados。

我希望有人能帮帮忙。

在该示例中,我删除了许多仅用于stackoverflow的if (ret < 0),它们已包含在我的完整示例中。

最佳答案

即使调用c_str()函数,Ceph缓冲区列表结构实际上也不会以NULL结尾。 (对不起那个不好的设计!)

因此,当您调用bufferlist :: c_str()并将其提供给字符串构造函数时,它将具有任意长度,直到其后的第一个随机NULL字节为止。您可以通过获取长度并在构造字符串时显式设置它来解决此问题。

08-07 03:07