MongoDB学习笔记(五) MongoDB文件存取操作

由于MongoDB的文档结构为BJSON格式(BJSON全称:Binary JSON),而BJSON格式本身就支持保存二进制格式的数据,因此可以把文件的二进制格式的数据直接保存到MongoDB的文档结构中。但是由于一个 BJSON的最大长度不能超过4M,所以限制了单个文档中能存入的最大文件不能超过4M。为了提供对大容量文件存取的支持,samus驱动提供了 “GridFS”方式来支持,“GridFS”方式文件操作需要引入新的程序集“MongoDB.GridFS.dll”。下面我们分别用两种方式来实 现。

一、在文档对象中存取文件

当文件大小较小的时候,直接存入文档对象实现起来更简洁。比如大量图片文件的存取等,一般图片文件都不会超过4M。我们先实现一个上传图片存入数据库,再取出来写回页面的例子:

1. 把图片存到BJSON中

复制代码 代码如下:

/// <summary>
/// 把图片存到BJSON中
/// </summary>
public void SaveImgBJSON(byte[] byteImg)
{
Document doc = new Document();
doc["ID"] = 1;
doc["Img"] = byteImg;
mongoCollection.Save(doc);
}

2. 获取BJSON方式存储的图片字节数据

复制代码 代码如下:

/// <summary>
/// 获取BJSON方式存储的图片字节数据
/// </summary>
public byte[] GetImgBJSON()
{
Document doc= mongoCollection.FindOne(new Document { { "ID", 1 } });
return doc["Img"] as Binary;
}

上面两段代码是在对MongoDB相关操作进行BLL封装类中添加的两个方法,封装方式查看上节内容。下面看看在webform中如何调用:

在界面拖出一个FileUpload控件和一个Button控件,页面cs类加如下方法:

复制代码 代码如下:

protected void Button1_Click(object sender, EventArgs e)
{
ImgBLL imgBll = new ImgBLL();
imgBll.DeleteAll();
imgBll.SaveImgBJSON(FileUpload1.FileBytes);
Response.BinaryWrite(imgBll.GetImgBJSON());
}

二、用GridFS方式存取文件

在实现GridFS方式前我先讲讲它的原理,为什么可以存大文件。驱动首先会在当前数据库创建两个集合:"fs.files" 和"fs.chunks"集合,前者记录了文件名,文件创建时间,文件类型等基本信息;后者分块存储了文件的二进制数据(并支持加密这些二进制数据)。分 块的意思是把文件按照指定大小分割,然后存入多个文档中。"fs.files"怎么知道它对应的文件二进制数据在哪些块呢?那是因为 在"fs.chunks"中有个"files_id"键,它对应"fs.files"的"_id"。"fs.chunks"还有一个键(int 型)"n",它表明这些块的先后顺序。这两个集合名中的"fs"也是可以通过参数自定义的。

如果你只是想知道怎么用,可以忽略上面这段话,下面将用法:

1. GridFS方式的文件新建,读取,删除

复制代码 代码如下:

private string GridFsSave(byte[] byteFile)
{
string filename = Guid.NewGuid().ToString();

//这里GridFile构造函数有个重载,bucket参数就是用来替换那个创建集合名中默认的"fs"的。
GridFile gridFile = new GridFile(mongoDatabase);
using (GridFileStream gridFileStream = gridFile.Create(filename))
{
gridFileStream.Write(byteFile, 0, byteFile.Length);
}
return filename;
}

private byte[] GridFsRead(string filename)
{
GridFile gridFile = new GridFile(mongoDatabase);
GridFileStream gridFileStream = gridFile.OpenRead(filename);
byte[] bytes = new byte[gridFileStream.Length];
gridFileStream.Read(bytes, 0, bytes.Length);
return bytes;
}

private void GridFsDelete(string filename)
{
GridFile gridFile = new GridFile(mongoDatabase);
gridFile.Delete(new Document("filename", filename));
}

2. 再次封装GridFS操作,新文档只存储文件名称,相当于只是一个键,新文档还可以有除“文件名”之外其他的键。

复制代码 代码如下:

/// <summary>
/// 把图片存到GridFS中
/// </summary>
public void SaveImgGridFS(byte[] byteImg)
{
string filename = GridFsSave(byteImg);

Document doc = new Document();
doc["ID"] = 1;
doc["filename"] = filename;
mongoCollection.Save(doc);
}

/// <summary>
/// 获取GridFS方式存储的图片
/// </summary>
public byte[] GetImgGridFS()
{
Document doc = mongoCollection.FindOne(new Document { { "ID", 1 } });
string filename = doc["filename"].ToString();
return GridFsRead(filename);
}

三、小结

文件存取应该不是很难,值得注意的地方是:用第一种方式从文档中读出二进制数据时,一定要将类型转换为“Binary”类型;还有系统自带的键“_id”,它也不是string类型,是“Oid”类型的。

作者:李盼(Lipan)
出处:[Lipan] (http://www.cnblogs.com/lipan/)

(0)

相关推荐

  • MongoDB学习笔记(一) MongoDB介绍与安装方法

    最近开始学习非关系型数据库MongoDB,却在博客园上找不到比较系统的教程,很多资料都要去查阅英文网站,效率比较低下。本人不才,借着自学的机会把心得体会都记录下来,方便感兴趣的童鞋分享讨论 一、前言 ...

  • MongoDB学习笔记(六) MongoDB索引用法和效率分析

    MongoDB中的索引其实类似于关系型数据库,都是为了提高查询和排序的效率的,并且实现原理也基本一致。由于集合中的键(字段)可以是普通数据 类型,也可以是子文档。MongoDB可以在各种类型的键上创建 ...

  • MongoDB学习笔记(二) 通过samus驱动实现基本数据操作

    传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由 (database)、集合(collection)、文档对象(docume ...

  • MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据

    下面我们将逐步讲解怎么在MVC模式下将MongoDB数据读取,并展示在前台Jqgrid表格上。这个“简易系 统”的基本设计思想是这样的:我们在视图层展示表格,Jqgrid相关Js逻辑全部放在一个Js文 ...

  • MongoDB学习笔记(四) 用MongoDB的文档结构描述数据关系

    MongoDB的集合(collection)可以看做关系型数据库的表,文档对象(document)可以看做关系型数据库的一条记录。但两者并 不完全对等。表的结构是固定的,MongoDB集合并没有这个约 ...

  • 学习通APP中怎么做学习笔记

    今天就跟大家介绍一下学习通APP中怎么做学习笔记的具体操作步骤.1. 首先打开手机上的学习通app,进入主页面后,点击页面右下角的我选项,进入我的页面后,点击下方的"笔记本"选项. ...

  • linux c学习笔记:[1]gcc的使用方法

    个人学习笔记,所用课本是<linux 软件工程师(C语言)实用教程>,希望对不懂的人起到帮助作用! 本篇讲解gcc的使用方法. GCC相关 01 gcc编译常用格式: gcc  C源文件 ...

  • 怎样学习用五笔输入法打字

    五笔输入法以其打字速度快而受到用户的喜爱,但用五笔输入法要先进行学习.对初学者来说,需要了解学习五笔输入法的程序.选择一种五笔输入法,在打字学习软件中就用这个输入法来学习五笔输入. 操作方法 01 学 ...

  • linux学习笔记之linux文件管理

    内容: #文件系统及Shell的基本概念 #文件及目录操作命令 #VI的使用 #软件包的管理 一、文件系统及Shell的基本概念 1.文件系统的含义 文件系统是用来管理和组织保存在磁盘驱动器上数据的系 ...