以下内容摘自MongoDB官方文档:GridFS是一种将大型文件存储在MongoDB的文件规范。所有官方支持的驱动均实现了GridFS规范。缘起数据库支持以BSON格式保存二进制对象。但是MongoDB中BSON对象最大不能超过4MB。GridFS规范提供了一种透明的机制,可以
以下内容摘自MongoDB官方文档:
GridFS是一种将大型文件存储在MongoDB的文件规范。所有官方支持
的驱动均实现了GridFS
规范。
缘起
数据库支持以BSON格式保存二进制对象。
但是MongoDB中BSON对象最大不能超过4MB。
GridFS 规范提供了一种透明的机制,可以将一个大文件分割成为多个较小的文档。这将容许
我们有效的保存大的文件对象,特别对于那些巨大的文件,比如视频。
实现
为实现这点,该规范指定了一个将文件分块的标准。每个文件都将在文件集合对象中保存一
个元数据对象,一个或多个块对象可被组合保存在一个块集合中。文件
如何被分块保存的细
节可以参看GridFS Specification; 大多数情况下,你无需了解此规范中细节,而可将注意
力放在各个
语言版本的驱动中有关GridFS
API的部分或是如何使用mongofiles工具上。
GridFS规格
介绍
GridFS是一个大对象存储在MongoDB规范。它通过分割成小块,大小通常在256K的大对象。
每块存储为一个单独的文件块收集在一个块。有关该文件的元数据,包括文件名,内容类型,
以及任何可选的
开发所需要的信息,被存储为一个文件 放在一个文件集中。因此,对于任何
给定的文件的存储都使用GridFS,将存在于文件中的一个文件集合和一个或多个chunks的
数据块 。
如果你只是对使用GridFS感兴趣,只需看文档的存储文件 。如果您想了解GridFS执行,请
继续阅读。
规范
存储收藏
GridFS使用两个集合来存储数据:
* files 包含元数据对象
* chunks 包含其他一些解释信息的二进制块
为了使多个GridFS命名为一个单一的数据库,文件和块的集合有一个前缀命名。默认情况下,
前缀是fs的。,所以任何默认GridFS存储将包括集合命名fs.files和fs.chunks。驱动有
可能要改变这个前缀,所以你可以实例,有另一个GridFS命名空间存储照片收藏的具体位置
为:photos.files和photos.chunks。
========================================第2页========================================
下面是一个标准的
Java接口GridFS例子:
/*
* 使用默认的根集合-必须得到支持
*/
GridFS myFS = new GridFS(myDatabase);
// returns a default GridFS
(e.g.
"fs" root collection)
myFS.storeFile(new File("/tmp/largething.mpg")); // saves
the file into the "fs"
GridFS store
/*
* 指定使用的根集合 - 可选
*/
GridFS myCOntracts= new GridFS(myDatabase, "contracts");
// returns a GridFS
where "contracts" is root
myFS.retrieveFile("smithco", new
File("/tmp/smithco_20090105.pdf")); //retrieves
object whose filename is "smithco"
files
文件集合中的文档包含以下属性:
{
"_id" : ,
// unique ID for this file
"length" : data_number, // size of
the file in bytes
"chunkSize" : data_number, // size of each
of the chunks. Default is 256k
"uploadDate" : data_date, // date when
object first stored
"md5" : data_string //
result of running the "filemd5" command on this
file's chunks
}
任何其他所需的字段可能会被添加到档案文件,常见的包括以下内容:
{
"filename" : data_string,
// human name for the file
"contentType" : data_string,
// valid mime type for the object
"aliases" : data_array of data_string, // optional
array of alias strings
"metadata" : data_object,
// anything the user wants to store
}
chunks
{
========================================第3页========================================
"_id" : , // object id of
the chunk in the _chunks collection
"files_id" : , // _id of the
corresponding files collection entry
"n" : chunk_number, // chunks
are numbered in order, starting with 0
"data" : data_binary, // the chunk's
payload as a BSON binary type
}
注释:
*
_id可任意指定.对于任何MongoDB文件,默认的将是一个BSON对象ID。
* 该files_id是一个包含文件的集合项_id属性的外键
Indexes
db.fs.chunks.ensureIndex({files_id:1, n:1}, {unique:
true});
这样,一个块有效地利用它的files_id和 n值可以被检索。请注意,GridFS实现应该使用
findOne得到chunks,不要放弃打开游标查询所有chunks。因此,为了得到第一个块,我们
可以这样做:
db.fs.chunks.findOne({files_id: myFileID, n: 0});
GridFS
GridFS是一个大的文件存储在MongoDB的规范。所有的驱动
程序支持实现GridFS规范
。
理由
该数据库支持存储本地的BSON对象二进制的数据。然而,在MongoDB BSON对象被限于大小
为4MB。GridFS规范提供了一种透明的机制划分大文件在多个文档。这使我们能够有效地存
储大对象,并在特别是大型文件,如视频,案例,许可证范围操作(例如,只取前N个字节
的文件)。
========================================第4页========================================
执行
为了促进这一点,一个标准是指定的文件组块。在一个文件的集合,每个文件有一元数据对
象,以及一个或多个chunk对象在一个chunk集合。这些怎样被存储的详细可以在GridFS
规范找到,但是,你并不真的需要阅读,相反地,只要看一下GridFS API在每个语言的客户
端驱动程序或mongofiles工具。
语言支持
大部分驱动包括GridFS实施;以下语言没有列出,请检查驱动程序的API文档。(如果不包括
支持的语言,看到GridFS 规范 -执行一个处理程序通常是很容易的。)
相关驱动程序文件:Java, Perl,
PHP, Python, Ruby
GridFS Tools
File Tools
例如:
$ ./mongofiles list
connected to: 127.0.0.1
$ ./mongofiles put libmongoclient.a
connected to: 127.0.0.1
done!
$ ./mongofiles list
connected to: 127.0.0.1
libmongoclient.a 12000964
$ cd /tmp/
$ ~/work/mon/mongofiles get libmongoclient.a
$ ~/work/mongo/mongofiles get libmongoclient.a
connected to: 127.0.0.1
========================================第5页========================================
done write to: libmongoclient.a
$ md5 libmongoclient.a
MD5 (libmongoclient.a) =
23a52d361cfa7bad98099c5bad50dc41
$ md5 ~/work/mongo/libmongoclient.a
MD5 (/Users/erh/work/mongo/libmongoclient.a) =
23a52d361cfa7bad98099c5bad50dc41
使用java操作MongoDB,实现文件的写入与读取。
package com.efuture.dao;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import com.mongodb.DB;
import com.mongodb.Mongo;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;
public class MongoDBFileTest {
static DB test=null;
static GridFS gridFS=null;
public static void main(String[] args) throws
Exception {
long
start=System.currentTimeMillis();
Mongo mOngo= new
Mongo("127.0.0.1", 27017); //数据库地址,端口号
test = mongo.getDB("test");
// 数据库名称
gridFS = new GridFS(test );
String
fileName="eclipse-jee-galileo-SR2-linux-gtk.tar.gz"; //
读取189
M 的文件
String
fileNameO="eclipse.zip"; // 写入文件名称
MongoDBFileTest mon= new
MongoDBFileTest();
File fileIN = new File
("/home/liuxiaoming/公共的/"+fileName);
File fileOUT = new File
("/home/liuxiaoming/公共的/"+fileNameO);
========================================第6页========================================
/**
* 将文件存入 MongoDB
数据库中
*/
//
mon.saveFile(fileIN, fileName);
// long
end=System.currentTimeMillis();
// System.out.println
(end -start);
/**
*
从MongoDB中读取数据,并且写入磁盘
*/
List>
list=mon.findFilesByName(fileName);
GridFSDBFile
gridFSDBFile=(GridFSDBFile) list.get(0) ;
gridFSDBFile.writeTo(fileOUT);
System.out.println
(list.size() );
}
/**
* 写入文件
* @param fileName
*/
public void saveFile(File
file,String fileName) {
try {
GridFSFile mOngofile=gridFS.createFile(file);
mongofile.put("filename", fileName);
mongofile.put("uploadDate", new Date() );
mongofile.put("contentType",fileName.substring(
fileName.lastIndexOf(".") ));
mongofile.save();
} catch
(IOException e) {
e.printStackTrace();
}
}
/**
* 读取文件
* @param fileName
*/
public
List findFilesByName(String fileName) {
List list =gridFS.find(fileName);
return list;
}
}