MongoDB GridFS 与Linux下C交互

参考文章

http://mongoc.org/libmongoc/current/mongoc_gridfs_t.html
https://www.runoob.com/mongodb/mongodb-gridfs.html
https://www.cnblogs.com/bonelee/p/6568211.html

mongo

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mydb    0.000GB
test    0.014GB
> use test
switched to db test
> show tables;
fs.chunks
fs.files
test
> db.fs.files.find()
{ "_id" : ObjectId("5ebcd406b90d7867dd05f182"), "chunkSize" : 261120, "filename" : "f1", "length" : NumberLong(269094), "uploadDate" : ISODate("2020-05-14T05:15:50Z") }
{ "_id" : ObjectId("5ebcd46486368051170f5372"), "chunkSize" : 261120, "filename" : "f2", "length" : NumberLong(269094), "uploadDate" : ISODate("2020-05-14T05:17:24Z") }
{ "_id" : ObjectId("5ebcd49b86368051170f5373"), "chunkSize" : 261120, "filename" : "f3", "length" : NumberLong(5131135), "uploadDate" : ISODate("2020-05-14T05:18:19Z") }
{ "_id" : ObjectId("5ebcd6f386368051170f5374"), "chunkSize" : 261120, "filename" : "007.jpg", "length" : NumberLong(52029), "uploadDate" : ISODate("2020-05-14T05:28:19Z") }
{ "_id" : ObjectId("5ebceae6d4a630373305cd42"), "chunkSize" : 261120, "filename" : "007_2.jpg", "length" : NumberLong(52029), "uploadDate" : ISODate("2020-05-14T06:53:26Z") }
{ "_id" : ObjectId("5ebcfb7857e320163e1bfc92"), "chunkSize" : 261120, "filename" : "mon2.c", "length" : NumberLong(4546), "uploadDate" : ISODate("2020-05-14T08:04:08Z") }
{ "_id" : ObjectId("5ebcfd8cebea31294a6ec792"), "chunkSize" : 261120, "filename" : "mon2.c", "length" : NumberLong(4546), "uploadDate" : ISODate("2020-05-14T08:13:00Z") }
> 

主要是这两个集合
fs.chunks
fs.files

几个关键的key
{ “_id” : ObjectId(“5ebcd406b90d7867dd05f182”), “chunkSize” : 261120, “filename” : “f1”, “length” : NumberLong(269094), “uploadDate” : ISODate(“2020-05-14T05:15:50Z”) }
_id 对象id
filename 文件名
length 文件大小

利用相关api可以实现文件上传、下载


/*

gcc -o test mongo_ftp.c \
-I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \
-lmongoc-1.0 -lbson-1.0
*/

#include 
#include 
#include 
#include 
#include 

int
	main (int argc, char *argv[])
{
	mongoc_gridfs_t *gridfs;
	mongoc_gridfs_file_t *file;
	mongoc_gridfs_file_list_t *list;
	mongoc_gridfs_file_opt_t opt = {0};
	mongoc_client_t *client;
	const char *uri_string = "mongodb://127.0.0.1:27017/?appname=gridfs-example";
	mongoc_uri_t *uri;
	mongoc_stream_t *stream;
	bson_t filter;
	bson_t opts;
	bson_t child;
	bson_error_t error;
	ssize_t r;
	char buf[4096];
	mongoc_iovec_t iov;
	//const char *filename;
	//const char *command;
	bson_value_t id;

	int fid = 1;

	char filename[64] = {0};
	char command[64] = {0};
	char local_save_name[64] = {0};

	/*
	if (argc < 2) {
	fprintf (stderr, "usage - %s command ...\n", argv[0]);
	return EXIT_FAILURE;
	}
	*/

	mongoc_init ();

	iov.iov_base = (void *) buf;
	iov.iov_len = sizeof buf;

	/* connect to localhost client */
	uri = mongoc_uri_new_with_error (uri_string, &error);
	if (!uri) {
		fprintf (stderr,
			"failed to parse URI: %s\n"
			"error message:       %s\n",
			uri_string,
			error.message);
		return EXIT_FAILURE;
	}

	client = mongoc_client_new_from_uri (uri);
	assert (client);
	mongoc_client_set_error_api (client, 2);

	/* grab a gridfs handle in test prefixed by fs */
										//名称为test的数据库
	gridfs = mongoc_client_get_gridfs (client, "test", "fs", &error);
	assert (gridfs);

	//command = argv[1];
	//filename = argv[2];
	while(1){

		fflush(stdin);
		scanf("%s",command);//读取命令

		if (strcmp (command, "read") == 0) {

			/*
			if (argc != 4) {
			fprintf (stderr, "usage - %s read filename local_save_name\n", argv[0]);
			return EXIT_FAILURE;
			}*/
			scanf("%s %s",filename,local_save_name);

			file = mongoc_gridfs_find_one_by_filename (gridfs, filename, &error);
			assert (file);

			stream = mongoc_stream_gridfs_new (file);
			assert (stream);

			for (;;) {
				r = mongoc_stream_readv (stream, &iov, 1, -1, 0);

				assert (r >= 0);

				if (r == 0) {
					break;
				}

				//size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
				//输出到控制台

				FILE*fp = fopen(local_save_name,"w");
				if(!fp){
					printf("fopen error\n");
					exit(1);
				}


				if (fwrite (iov.iov_base, 1, r, fp) != r) {
					MONGOC_ERROR ("Failed to write to stdout. Exiting.\n");
					exit (1);
				}

				fclose(fp);
			}

			mongoc_stream_destroy (stream);
			mongoc_gridfs_file_destroy (file);
		} else if (strcmp (command, "list") == 0) {
			bson_init (&filter);

			bson_init (&opts);
			bson_append_document_begin (&opts, "sort", -1, &child);
			BSON_APPEND_INT32 (&child, "filename", 1);
			bson_append_document_end (&opts, &child);

			list = mongoc_gridfs_find_with_opts (gridfs, &filter, &opts);

			bson_destroy (&filter);
			bson_destroy (&opts);

			while ((file = mongoc_gridfs_file_list_next (list))) {
				const char *name = mongoc_gridfs_file_get_filename (file);
				printf ("%s\n", name ? name : "?");

				mongoc_gridfs_file_destroy (file);
			}

			mongoc_gridfs_file_list_destroy (list);
		} 
		else if (strcmp (command, "write") == 0) {//write 写文件名 本地文件名
			scanf("%s %s",filename,local_save_name);
			/*
			if (argc != 4) {
			fprintf (stderr, "usage - %s write filename input_file\n", argv[0]);
			return EXIT_FAILURE;
			}
			*/

			stream = mongoc_stream_file_new_for_path (local_save_name, O_RDONLY, 0);
			assert (stream);

			opt.filename = filename;

			/* the driver generates a file_id for you */
			file = mongoc_gridfs_create_file_from_stream (gridfs, stream, &opt);
			assert (file);

			//id.value_type = BSON_TYPE_INT32;//对应mongodb文档的_id的类型
			//id.value.v_int32 = fid;//对应mongodb文档的_id的值

			//id.value_type = BSON_TYPE_OID;//对应mongodb文档的_id的类型
			//id.value.v_oid = fid;
			//fid++;

			/* optional: the following method specifies a file_id of any
			BSON type */

			//干脆不人工设置了,mongo会自动设置对象的_id,
			//if (!mongoc_gridfs_file_set_id (file, &id, &error)) {
			//   printf("!mongoc_gridfs_file_set_id\n");
			//   fprintf (stderr, "%s\n", error.message);
			//   return EXIT_FAILURE;
			//}

			if (!mongoc_gridfs_file_save (file)) {
				mongoc_gridfs_file_error (file, &error);
				fprintf (stderr, "Could not save: %s\n", error.message);
				return EXIT_FAILURE;
			}

			mongoc_gridfs_file_destroy (file);
		} else {
			fprintf (stderr, "Unknown command");
			return EXIT_FAILURE;
		}

	}

	mongoc_gridfs_destroy (gridfs);
	mongoc_uri_destroy (uri);
	mongoc_client_destroy (client);

	mongoc_cleanup ();

	return EXIT_SUCCESS;
}


/*
typedef enum {
BSON_TYPE_EOD = 0x00,
BSON_TYPE_DOUBLE = 0x01,
BSON_TYPE_UTF8 = 0x02,
BSON_TYPE_DOCUMENT = 0x03,
BSON_TYPE_ARRAY = 0x04,
BSON_TYPE_BINARY = 0x05,
BSON_TYPE_UNDEFINED = 0x06,
BSON_TYPE_OID = 0x07,
BSON_TYPE_BOOL = 0x08,
BSON_TYPE_DATE_TIME = 0x09,
BSON_TYPE_NULL = 0x0A,
BSON_TYPE_REGEX = 0x0B,
BSON_TYPE_DBPOINTER = 0x0C,
BSON_TYPE_CODE = 0x0D,
BSON_TYPE_SYMBOL = 0x0E,
BSON_TYPE_CODEWSCOPE = 0x0F,
BSON_TYPE_INT32 = 0x10,
BSON_TYPE_TIMESTAMP = 0x11,
BSON_TYPE_INT64 = 0x12,
BSON_TYPE_DECIMAL128 = 0x13,
BSON_TYPE_MAXKEY = 0x7F,
BSON_TYPE_MINKEY = 0xFF,
} bson_type_t;

typedef struct _bson_value_t {
bson_type_t value_type;
union {
bson_oid_t v_oid;
int64_t v_int64;
int32_t v_int32;
int8_t v_int8;
double v_double;
bool v_bool;
int64_t v_datetime;
struct {
uint32_t timestamp;
uint32_t increment;
} v_timestamp;
struct {
uint32_t len;
char *str;
} v_utf8;
struct {
uint32_t data_len;
uint8_t *data;
} v_doc;
struct {
uint32_t data_len;
uint8_t *data;
bson_subtype_t subtype;
} v_binary;
struct {
char *regex;
char *options;
} v_regex;
struct {
char *collection;
uint32_t collection_len;
bson_oid_t oid;
} v_dbpointer;
struct {
uint32_t code_len;
char *code;
} v_code;
struct {
uint32_t code_len;
char *code;
uint32_t scope_len;
uint8_t *scope_data;
} v_codewscope;
struct {
uint32_t len;
char *symbol;
} v_symbol;
} value;
} bson_value_t;
*/

你可能感兴趣的:(mongodb)