参考文章
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;
*/