嘿,我试图使用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!
,但是由于某种原因,有时我会将r
,m
或z
附加到字符串中,所以我一无所知对这个。我试过用
std::vector<uint8_t>
到字符串,也返回,结果相同。这就是我最初发现问题的方式。我正在为C ++使用最新的librados。
我希望有人能帮帮忙。
在该示例中,我删除了许多仅用于stackoverflow的
if (ret < 0)
,它们已包含在我的完整示例中。 最佳答案
即使调用c_str()函数,Ceph缓冲区列表结构实际上也不会以NULL结尾。 (对不起那个不好的设计!)
因此,当您调用bufferlist :: c_str()并将其提供给字符串构造函数时,它将具有任意长度,直到其后的第一个随机NULL字节为止。您可以通过获取长度并在构造字符串时显式设置它来解决此问题。