在计算机上,文档管理通常是通过操作系统进行文件管理的,例如在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内置一套文件系统名为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)