使用pymongo从GridFS获取图像
我正在玩MongoDB和pymongo这个接口。我可以把一个图片文件放进GridFS,感觉这很简单:
>>> f = open('myimage.jpg', 'r')
>>> fs = gridfs.GridFS(db)
>>> fid = fs.put(f)
>>> fid
ObjectId('4efde2c27c7778121800000a')
看起来操作成功了。我也可以用返回的_id来查询GridFS:
>>> fs.exists(fid)
True
但是我似乎无法把整个文件取出来,感觉我只拿到了一个小块?
>>> fs.get(fid).read()
'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00Z\x00Z\x00\x00\xff\xdb\x00C\x00
\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01
\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02\x01\x01
\x02\x01\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x02\x01\x02\x02\x02\x02\x02\x02
\x02\x02\x02\x02\xff\xdb\x00C\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x0
1\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x0
2\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x0
2\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\xff\xc0\x00\x11\x08\x03\x8d\x0
2X\x03\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\
x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\
t\n\x0b\xff\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\
x00\x01}\x01\x02\x03\x00\x04\x11\x05\x12!1A\x06\x13Qa\x07"q\x142\x81\x91\xa1\x08
#B\xb1\xc1\x15R\xd1\xf0$3br\x82\t\n\x16\x17\x18\x19'
>>> f.tell()
352256L
我对原始文件做了一个tell(),可以看到它的大小远远大于我从GridFS拿到的内容。如果我对从GridFS取回的文件做tell(),结果大约是274。(我知道tell()只是告诉你文件中的指针位置,但它可以给你一个读取后文件大小的感觉。)
显然我在这里漏掉了什么!我该如何才能把整个文件从GridFS取出来呢?
我正在使用mongodb的2.0.2版本和pymongo的2.1版本,Python版本是2.7。
3 个回答
1
试着把'r'改成'rb',就像这样:>>> f = open('myimage.jpg', 'rb')
根据你使用的系统(Windows/Linux/Mac),这可能会引发一些问题。
1
你可以检查一下GridFS是否真的保存了整个文件,也就是说,你在mongo控制台中没有只写入文件的一部分。这样做会列出你的图片和其他文件,以及每个文件的长度。这样你就可以确认GridFS是否真的保存了你的整个文件。
db.fs.files.find().pretty()
如果它没有完整保存你的文件,那可能是你在写入GridFS的时候搞得有点乱(就像@dcrosta说的那样)。
*注意:在上面的命令中,把你的集合名称替换成“fs”。比如:
db.<my_collection_name>.files.find().pretty()
如果你有很多文件的话,可以试试:
db.<my_collection_name>.files.findOne({'_id' : ObjectId("your object id as a hex string")})
2
获取数据并输出到outputdata
outputdata =fs.get(stored).read()
定义文件路径并打开写入模式
outfilename = "path to output file"
output= open(outfilename,"w")
写入数据并关闭文件
output.write(outputdata)
output.close()