关键词

MongoDB系列教程(八):GridFS存储详解

MongoDB系列教程(八):GridFS存储详解

简介

在前几篇教程中,我们已经介绍了MongoDB中的基本用法,比如数据库的创建、集合的创建和基本的CRUD操作等。在本篇教程中,我们将进一步介绍MongoDB的高级功能——GridFS存储。

GridFS是一种MongoDB提供的存储机制,它可以用于存储超大型数据,比如视频、音频、PDF等文件类型。在GridFS中,将文件存储为二进制数据块,然后将所有的二进制数据块合并成一个整体。文件在存储到GridFS后,可以被任何连接到MongoDB的应用程序所访问和使用。

GridFS的组成部分

文件存储

当将文件存储到GridFS中,它会被切割成多个块。每个块都会被存储成一个文档。文档包括块的数据和元数据,比如文件名、上传时间、文件类型等。

文件信息存储

除了文件存储,GridFS还将文件信息存储在文件存储的集合中,这个集合称为文件信息集合。文件信息集合包含一个文档,其中包含文件的基本元数据信息,比如文件名、文件类型、上传日期、块的大小等。

GridFS文件上传

上传小文件

上传小文件时,使用MongoDB提供的“db.fs.files”集合。

示例代码:

db.fs.files.insert({
    filename: "small_file.txt",
    contentType: "text/plain"
});

var fileData = "这是一段小文件数据。"
db.fs.chunks.insert({
    files_id: fileId,
    data: BinData(0, fileData)
});

上传大文件

当上传大文件时,需要按照文件大小将文件进行分块,并将每个块作为一个文档存储到“db.fs.chunks”集合中。文件的基本元数据信息存储在文件信息集合中。

示例代码:

db.fs.files.insert({
    filename: "big_file.txt",
    chunkSize: 1024*1024,  // 每块大小为1M
    contentType: "text/plain"
});

var fs = require("fs");
var fileSize = fs.statSync("big_file.txt").size;
var chunkSize = 1024*1024;  // 每块大小为1M
var numChunks = Math.ceil(fileSize/chunkSize);

var fileId = ObjectId();  // 创建文件ID

for (var i=0; i<numChunks; i++) {
    var buffer = new Buffer(chunkSize);
    var bytesRead = fs.readSync(fd, buffer, 0, chunkSize, i*chunkSize);
    db.fs.chunks.insert({
        files_id: fileId,
        n: i,
        data: buffer.slice(0, bytesRead)
    });
}

db.fs.files.update({
    _id: fileId
},{
    $set: {
        length: fileSize,
        uploadDate: new Date()
    }
});

GridFS文件下载

下载小文件

下载小文件时,可以从“db.fs.chunks”集合中取出文件的二进制数据,然后将数据写入指定的文件中。

示例代码:

var fileId = ObjectId("59b636e3c0afa9172cf3e431");  // 文件ID

var fileDoc = db.fs.files.findOne({
    _id: fileId
});

if (!fileDoc) {
    print("文件不存在!");
    return;
}

var filename = fileDoc.filename;
var contentType = fileDoc.contentType;

var cursor = db.fs.chunks.find({
    files_id: fileId
}).sort({n: 1});

var bufferArray = [];

while (cursor.hasNext()) {
    bufferArray.push(cursor.next().data);
}

var fileData = Buffer.concat(bufferArray)

require("fs").writeFileSync(filename, fileData);

print("文件下载成功!");

下载大文件

下载大文件时,需要循环遍历“db.fs.chunks”集合,依次取出每个块的数据,然后将数据写入指定的文件中。

示例代码:

var fileId = ObjectId("59b636e3c0afa9172cf3e431");  // 文件ID

var fileDoc = db.fs.files.findOne({
    _id: fileId
});

if (!fileDoc) {
    print("文件不存在!");
    return;
}

var filename = fileDoc.filename;
var contentType = fileDoc.contentType;

var cursor = db.fs.chunks.find({
    files_id: fileId
}).sort({n: 1});

var fd = require("fs").openSync(filename, "w");

while (cursor.hasNext()) {
    var chunk = cursor.next();
    var buffer = chunk.data.buffer;
    require("fs").writeSync(fd, buffer, 0, buffer.byteLength, chunk.n*fileDoc.chunkSize);
}

require("fs").closeSync(fd);

print("文件下载成功!");

总结

本篇教程介绍了MongoDB中的GridFS存储机制,讲解了GridFS文件存储和下载的实现方法,并附带示例代码。GridFS是MongoDB中非常重要的组件之一,在实际应用中可以用于存储大型文件和数据。在进行存储和下载操作时,需要遵循GridFS的相关规范。

本文链接:http://task.lmcjl.com/news/14424.html

展开阅读全文