天天看點

C++使用mongo-cxx-driver進行檔案GridFS上傳下載下傳

源位址

#include <algorithm>
#include <iostream>
#include <ostream>

#include <bsoncxx/json.hpp>
#include <bsoncxx/stdx/make_unique.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/gridfs/bucket.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
#include <bsoncxx/types/bson_value/view.hpp>
#include <fstream>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/builder/basic/array.hpp>
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/string/to_string.hpp>
#include <bsoncxx/types.hpp>
#include <bsoncxx/types/bson_value/view.hpp>
#include <bsoncxx/builder/stream/array.hpp>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/builder/basic/document.hpp>
using namespace mongocxx;
using namespace bsoncxx;
using bsoncxx::stdx::make_unique;
using namespace bsoncxx;
using namespace builder::stream;

int main() {
	std::cout << "start" << std::endl;
	// 初始化連接配接
	mongocxx::instance inst{};
	mongocxx::client conn{ mongocxx::uri{/*資料庫位址使用者名密碼等資訊*/}};
	auto db = conn["test"];
	auto bucket = db.gridfs_bucket();


	mongocxx::gridfs::uploader up = bucket.open_upload_stream("img");

	std::ifstream fp;
	//以讀取方式打開jpg檔案
	fp.open("D:/2.png", std::ios::binary | std::ios::in);
	//定位到檔案末尾
	fp.seekg(0, fp.end);
	//獲得檔案總長度
	size_t allLength = fp.tellg();
	//将指針定位到檔案首
	fp.seekg(0, fp.beg);

	char* buff = new char[allLength + 10]{ 0 };
	fp.read(buff, allLength);

	up.write(reinterpret_cast<uint8_t*>(const_cast<char*>(buff)), allLength);

	delete[]buff;
	buff = nullptr;
	auto result = up.close();
	// 檔案唯一ID
	auto kk = result.id();


	/**************下載下傳示例***************/


	// 通過檔案的ID讀取檔案
	std::string idStr = "620f1faaf06f0000de000e52";
	// 構造oid構造函數參數
	bsoncxx::stdx::string_view fileIdSv = idStr;

	// 構造BSON格式ID
	auto bsonId = oid(fileIdSv);

	builder::stream::document build_doc;
	// 建構文檔
	build_doc << "id" << bsonId;
	// 擷取文檔視圖
	auto doc = build_doc.view();

	// 通過擷取文檔的值來轉化為bsoncxx::types::bson_value::view類型
	auto downloader = bucket.open_download_stream(doc["id"].get_value());
	// 檔案長度
	auto file_length = downloader.file_length();

	// 讀取位元組計數
	auto bytes_counter = 0;
	// 需要的緩沖區大小
	auto buffer_size = std::min(file_length, static_cast<std::int64_t>(downloader.chunk_size()));
	// 建立緩沖區
	auto buffer = make_unique<std::uint8_t[]>(static_cast<std::size_t>(buffer_size));

	// 檔案存儲位置
	std::fstream fq;
	fq.open("E:/Desktop/3.png", std::ios::binary | std::ios::out);

	// 循環接受下載下傳并寫入
	while (auto length_read =
		downloader.read(buffer.get(), static_cast<std::size_t>(buffer_size))) {
		bytes_counter += static_cast<std::int32_t>(length_read);
		fq.write(reinterpret_cast<char*>(const_cast<uint8_t*>(buffer.get())), length_read);
	}
	fq.close();

	std::cout << "總共接收位元組數" << bytes_counter << std::endl;
	return 0;
}