在计算机上,文档管理通常是通过操作系统进行文件管理的,例如在windows环境中的资源管理上,文件是存在树状的文件系统中。

如果把这些文件放置到数据库中是否更易于管理呢?显然,理论上是可行的,例如早期Lotus Domino专业文档管理数据库,如今,当MongoDB+GridFS出现后,可以更专业化管理非结构化文档。

方法一:对于小型文件,可以直接使用MongoDB进行存储管理。

'''
Created on 2019年9月5日

@author: xiaoyw
'''
import pymongo
import os

class MongoGridFS(object):
    '''
    classdocs
    '''
    UploadCache = "uploadcache"
    dbURL = "mongodb://localhost:27017"

    def __init__(self, params):
        '''
        Constructor
        '''
    #存入小型文件《4M    
    def upLoadSmallFile(self,file_coll,file_name,data_link):
        client = pymongo.MongoClient(self.dbURL)

        db = client["store"]
        file_dict = {
            "filename":"test",
            "filesize":100,
            "uploadDate":"2019-09-05 06:05:38.792Z"
            }

        collection = db[file_coll]
        fsize = os.path.getsize(file_name)
        file_dict["filesize"] = fsize
        with open(file_name, 'rb') as file_r:
            file_data = file_r.read()
            file_dict["file_data"] = file_data
            file_dict["filename"] = file_name
            file_ = collection.insert(file_dict)
            
        return file_
          
if __name__ == '__main__':
    a = MongoGridFS("")
    ll = a.upLoadSmallFile("SmallFiles", "MongoGridFS.py", "")
    print (ll)

mongodb存储小说视频 mongodb存储小文件_GridFS


方法二:MongoDB内置一套文件系统名为GridFS(Grid File System),我们可以使用它来存储大于16M的文件。

GridFS具有分布式管理文件的能力,可以突破一般文件系统对file的限制,分段存储,不像普通文件系统是整个存储的。这样读取大型文件时就不会占用大量的内存。

GridFS会将文件存储在两个Document里:

  • Chunks用来存储二进制数据
  • Files用于存储基本文件信息

gridfs介绍

GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等),适合于不常改变但是经常需要连续访问的大文件。GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中。

GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。

其中,files中存储文件的元信息,默认使用集合为fs.files,键定义如下:

  • _id 主键
  • length 文件所包含的字节数
  • chunkSize 组成文件的每个块的大小,单位为字节,默认值为256KB,可调整
  • uploadDate 文件被上传到GridFS的日期
  • md5 文件内容的MD5校验值,该值由服务器端测试得到
  • 每一个文件存储的各个chunk的files_id相同
'''
'''
Created on 2019年9月5日

@author: xiaoyw
'''
import pymongo
from gridfs import GridFS
from bson.objectid import ObjectId

class MongoGridFS(object):
    '''
    classdocs
    '''
    UploadCache = "uploadcache"
    dbURL = "mongodb://localhost:27017"


    def __init__(self, params):
        '''
        Constructor
        '''       
    #上传文件
    def upLoadFile(self,file_coll,file_name,data_link):
        client = pymongo.MongoClient(self.dbURL)

        db = client["store"]
        
        filter_condition = {"filename": file_name, "url": data_link}
        gridfs_col = GridFS(db, collection=file_coll)
        file_ = "0"
        query = {"filename":""}
        query["filename"] = file_name
                
        if gridfs_col.exists(query):
            print('已经存在该文件')
        else:
            
            with open(file_name, 'rb') as file_r:
                file_data = file_r.read()
                file_ = gridfs_col.put(data=file_data, **filter_condition)  # 上传到gridfs
                
                print(file_)

        
        return file_   
    # 按文件名获取文档
    def downLoadFile(self,file_coll,file_name,out_name,ver):
        client = pymongo.MongoClient(self.dbURL)

        db = client["store"]
        
        gridfs_col = GridFS(db, collection=file_coll)
        
        file_data = gridfs_col.get_version(filename=file_name, version=ver).read()
        
        with open(out_name, 'wb') as file_w:
            file_w.write(file_data)
        
    # 按文件_Id获取文档       
    def downLoadFilebyID(self,file_coll,_id,out_name):
        client = pymongo.MongoClient(self.dbURL)

        db = client["store"]
        
        gridfs_col = GridFS(db, collection=file_coll)
        
        O_Id = ObjectId(_id)
        
        gf = gridfs_col.get(file_id=O_Id)
        file_data = gf.read()
        with open(out_name, 'wb') as file_w:
            
            file_w.write(file_data)     
            
            
        return gf.filename    

if __name__ == '__main__':
    a = MongoGridFS("")
    #a.upLoadFile("pdf","MongoGridFS.py","")
    #a.downLoadFile("pdf","MongoGridFS.py","out2.p",2)
    ll = a.downLoadFilebyID("pdf","5d70a5b283a3c5104cd39346","out3.p")
    print (ll)