欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mongodb使用GridFS存储文件

程序员文章站 2022-05-18 14:32:03
...
先来看一个简单的例子:

public class Mongofs {
	
	private static final String USER = "rechard";
	private static final String PASS = "root";

	public static void main(String[] args) throws Exception 
	{
		
		Mongo m = new Mongo("localhost");
		DB db = m.getDB("newdb");
		boolean auth = db.authenticate(USER, PASS.toCharArray());

		if (auth) 
		{
			DBCollection coll = db.getCollection("testColl");
			db.requestStart();
			
			String file, newFilename, bucket, saveTo;			
			bucket = "fs";			
			newFilename = "mm";
			file = "/home/rechard/Pictures/105066115253.jpg";
			saveTo = "/home/rechard/Desktop/1.jpg";
			
			storeFile(db, bucket, file, newFilename);
			
			findSingleFileAndSaveAs(db, bucket, newFilename, saveTo);
			
			remove(db, bucket, newFilename);
			
			db.requestDone();
		} 	
	}

	/**
	 * 存储文件到mongo
	 * @param db
	 * @param bucket
	 * @param file
	 * @param fn
	 * @throws Exception
	 */
	static void storeFile(DB db, String bucket, String file, String fn)
			throws Exception
	{	
		File files = new File(file);
		// 创建一个GridFS实例
		GridFS gfs = new GridFS(db, bucket);
		GridFSInputFile gfsInput = gfs.createFile(files);
		// 指定一个GridFS实体的名字
		gfsInput.setFilename(fn);
		gfsInput.save();
	}

	/**
	 * 查找单个文件并保存
	 * @param db
	 * @param bucket
	 * @param fn
	 * @param saveTo
	 * @throws Exception
	 */
	static void findSingleFileAndSaveAs(DB db, String bucket, String fn, String saveTo) 
			throws Exception
	{
		GridFS gfs = new GridFS(db, bucket);
		GridFSDBFile dbFile = gfs.findOne(fn);
		//System.out.println(dbFile);
		if (dbFile != null) System.out.println("file size:" + dbFile.writeTo(saveTo));
	}
	
	/**
	 * 从mongodb删除文件
	 * @param db
	 * @param bucket
	 * @param fn
	 */
	static void remove(DB db, String bucket, String fn)
	{
		GridFS gfs = new GridFS(db, bucket);
		gfs.remove(fn);
	}
}


以上代码仅供测试和抛砖引玉,不作具体解决方法,详细信息请参考http://www.mongodb.org/

1.关于GridFS的构造函数参数bucket,我认为是一个标识符,即在newdb这个数据库下,不同的bucket代表不同的表(类型),而一个类型又可以包含多个文件。当然,bucket也不是必须要传的,如果觉得麻烦可以使用另一个Constructor-GridFS(DB db),默认bucket是"fs".

2.一个文件在mongodb里存储的文件,看起来是大概是这样的:
Mongodb使用GridFS存储文件
            
    
    博客分类: Java javamongodbcodeGridFSnosql 
详细的解释如下:
{
  "_id" : <unspecified>,                  // 文件的唯一标示id,由mongo自动创建
  "length" : data_number,                 // 文件的大小
  "chunkSize" : data_number,              // 块大小,默认是256k
  "uploadDate" : data_date,               // 存储时间
  "md5" : data_string                     // 文件的md5码
}


3.关于GridFSDBFile的writeTo方法有一个陷阱:
该方法名的三个重载方法实际上都存在返回值(long),他表示了这个文件的物理字节大小。如图:Mongodb使用GridFS存储文件
            
    
    博客分类: Java javamongodbcodeGridFSnosql 
当然你也可以不返回而直接调用这个方法。但请注意,前面最好加上GridFSDBFile对象不为空的判断,否则程序将有可能抛出异常。

4.GridFS的remove方法,意味着从mongodb中删除某个文件,返回值为void。这也正是让我警惕的地方。如果因为传参错误,remove方法接受了不正确的value或者空串,从而导致删除失败。想象一下,如果一张本该删除的图片却出现在首页上,但程序却没有给你哪怕一点儿提示!

ps:因为32位机器有2G的data size的限制,所以玩玩就行了。不过真正的服务器是不会有这个限制的,并且配合Nginx存取速度也十分理想,网上也已经有类似的测试结果。对于同类产品来,mongo的性能还是比较高的(虽然是以牺牲磁盘空间作为前提),而且也支持类似mysql的master-master replic双机热备份。缺点是,对于原子性的生产环境仍然不如传统的关系型数据库,这点很无奈。同时mongo也不支持事务。

总的来说,mongodb还是很不错的。也许未来几年,关系型数据库和NoSQL还会长期的并存下去。但谁又能说的准呢,就让我们拭目以待吧。
  • Mongodb使用GridFS存储文件
            
    
    博客分类: Java javamongodbcodeGridFSnosql 
  • 大小: 126.7 KB
  • Mongodb使用GridFS存储文件
            
    
    博客分类: Java javamongodbcodeGridFSnosql 
  • 大小: 183.1 KB