从MongoDB GridFS流式传输文件

不久前,我在Twitter上发布了自己的最新作品,即从MongoDB GridFS传输文件进行下载(而不是将整个文件存储到内存中然后提供服务),这是我取得的一个小胜利。 我答应就此事写博客,但不幸的是,我的特定用法与我的项目的领域有点相关,所以我不能仅仅展示它。 因此,我整理了一个示例node.js + GridFS应用程序 ,并在github上进行了共享,并将使用本文来解释我是如何实现的。 :)

GridFS模块

首先,特殊道具去tjholowaychuk谁在#node.js的IRC频道作出回应时,我问,如果任何人有运气使用GridFS的从猫鼬 。 我得到的很多代码都来自他与我分享的要旨。 无论如何,到代码。 我将描述如何使用gridfs,并在完成基础工作后说明从GridFS流式传输文件的过程是如此简单。

我创建了一个gridfs模块,该模块基本上通过mongoose(我在整个应用程序中使用)访问GridStore,该模块还可以共享将mongoose连接到mongodb服务器时创建的数据库连接。

mongoose = require "mongoose"
request  = require "request"GridStore = mongoose.mongo.GridStore
Grid      = mongoose.mongo.Grid
ObjectID = mongoose.mongo.BSONPure.ObjectID

如果我们不能在mongodb中添加任何文件,我们将无法获取文件,因此让我们创建一个putFile操作。

exports.putFile = (path, name, options..., fn) ->db = mongoose.connection.dboptions = parse(options)options.metadata.filename = namenew GridStore(db, name, "w", options).open (err, file) ->return fn(err)  if errfile.writeFile path, fnparse = (options) ->opts = {}if options.length > 0opts = options[0]if !opts.metadataopts.metadata = {}opts

实际上,这只是委托给GridStore中存在的putFile操作(作为mongodb模块的一部分)。 我也有一些逻辑来解析选项,如果没有提供默认值,则提供默认值。 要注意的一个有趣功能是,我将文件名存储在元数据中,因为当时我遇到了一个有趣的问题,即从gridFS检索的文件将id作为文件名(即使在mongo中查看发现文件名实际上是在数据库)。

现在进行get操作。 此方法的原始实现只是通过调用store.readBuffer()将内容作为缓冲区传递给所提供的回调,但是现在已更改为将结果存储对象传递给回调。 其值是调用者可以使用商店对象来访问元数据,contentType和其他详细信息。 用户还可以确定他们想如何读取文件(进入内存还是使用ReadableStream)。

exports.get = (id, fn) ->db = mongoose.connection.dbid = new ObjectID(id)store = new GridStore(db, id, "r",root: "fs")store.open (err, store) ->return fn(err)  if err# band-aidif "#{store.filename}" == "#{store.fileId}" and store.metadata and store.metadata.filenamestore.filename = store.metadata.filenamefn null, store

这段代码有一个小问题,它检查文件名和fileId是否相等。 如果是的话,它将检查是否设置了meta.filename并将store.filename设置为在那里找到的值。 我已经提出了这个问题,以后再进行调查。 :)

该模型

在我的特定实例中,我想将文件附加到模型。 在此示例中,我们假设我们有一个可以附加任意数量文件的应用程序(作业,贷款应用程序等)。 想想税收收据,完整的申请表以及其他扫描文件。

ApplicationSchema = new mongoose.Schema(name: Stringfiles: [ mongoose.Schema.Mixed ]
)
ApplicationSchema.methods.addFile = (file, options, fn) ->gridfs.putFile file.path, file.filename, options, (err, result) =>@files.push result@save fn

在这里,我将文件定义为混合对象类型的数组(意味着它们可以是任何东西)和方法addFile,该方法基本上采用一个至少包含路径和文件名属性的对象。 它使用它来将文件保存到gridfs并将结果的gridstore文件对象存储在files数组中(其中包含诸如id,uploadDate,contentType,名称,大小等之类的东西)。

处理要求

所有这些都插入到请求处理程序中,以处理向/ new提交的表单。 所有这一切都需要创建一个Application模型实例,从请求中添加上载的文件(在本例中,我们将文件字段命名为“ file”, 因此命名为req.files.file )并保存它。

app.post "/new", (req, res) ->application = new Application()application.name = req.body.nameopts = content_type: req.files.file.typeapplication.addFile req.files.file, opts, (err, result) ->res.redirect "/"

现在,所有这些工作的总和使我们可以非常轻松地从gridFS下载请求的文件,从而获得丰厚的回报。

app.get "/file/:id", (req, res) ->gridfs.get req.params.id, (err, file) ->res.header "Content-Type", file.typeres.header "Content-Disposition", "attachment; filename=#{file.filename}"file.stream(true).pipe(res)

在这里,我们只是通过id查找文件,并使用生成的文件对象来设置Content-Type和Content-Disposition字段,最后使用ReadableStream :: pipe将文件写出到响应对象(这是WritableStream的实例) )。 这是将数据从MongoDB流传输到客户端的魔力。

主意

这只是一个卑微的开始。 其他想法包括将gridfs完全封装在模型中。 更进一步,我们甚至可以将gridfs模型变成猫鼬插件,以允许完全黑盒使用gridfs。

随时检查该项目 ,让我知道您是否有进一步的想法。 叉开! :)

参考: 敏捷开发人员博客的Rant and Musings中我们的JCG合作伙伴 James Carr 从MongoDB GridFS流式传输文件


翻译自: https://www.javacodegeeks.com/2012/01/streaming-files-from-mongodb-gridfs.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Css Sprites 多张图片整合在一张图片上

CSS Sprites原理: CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数…

无需复杂插件即可从Eclipse启动和调试Tomcat

像Eclipse这样的现代IDE提供了各种插件来简化Web开发。 但是,我相信将Tomcat作为“常规” Java应用程序启动仍然可以提供最佳的调试体验。 大多数情况下,这是因为这些工具将Tomcat或任何其他servlet容器作为外部进程启动,然后在其上附加一个远…

flutter 国际化_Flutter 开发实战资源推荐

开工第一天,来点轻松的资源推荐。这是一篇实战类资源推荐,其实Flutter的入门资料官方已经做得很好了,如果你是零基础,还是建议先啃一遍官方的教程,然后再看以下实战资源,相信在你看官方课程中涉及到的一些疑…

JSF和“立即”属性–命令组件

JSF中的即时属性通常被误解。 如果您不相信我&#xff0c;请查看Stack Overflow 。 造成这种混乱的部分原因可能是输入&#xff08;即<h&#xff1a;inputText />&#xff09;和命令&#xff08;即<h&#xff1a;commandButton />&#xff09;组件都立即可用&#…

通过joystick遥感和按键控制机器人--11

原创博客&#xff1a;转载请表明出处&#xff1a;http://www.cnblogs.com/zxouxuewei/ 1.首先安装joystick遥控器驱动&#xff1a; sudo apt-get install ros-indigo-joystick-drivers ros-indigo-turtlebot-teleop 2.运行tulterbot机器人&#xff1a; roslaunch rbx1_bringup …

Nginx 实现网站 http、https 配置

在 nginx conf 目录下新建 ssl 目录&#xff0c;将申请的 ssl证书文件拷贝到此处&#xff1a; 修改 nginx 配置文件使支持 https&#xff0c;修改如下&#xff1a; server {listen 80;listen 443 ssl;ssl_certificate ssl/cert-xuexiyuan.cn.crt;ssl_certificat…

实用垃圾收集,第1部分–简介

这是我打算写的一系列博客文章的第一部分&#xff0c;其目的是解释垃圾回收在现实世界中的工作方式&#xff08;特别是在JVM中 &#xff09;。 我将介绍一些我认为对于充分理解垃圾收集对于实际目的是必要的理论&#xff0c;但是将其降至最低。 其动机是在各种情况下&#xff0…

mysql 导出 没有函数_没有MYSQL FILE函数的CSV导出

构建最佳CSV。你可以按照以下方式做。$filename data.csv;$csv_terminated "\n";$csv_separator ",";$csv_enclosed ";$csv_escaped "\\";$results array(1,2,3);// value$schema_insert ;$header array(a,b,c);// headerfor ($i 0…

html回复评论_3天内看了3000多篇《哈佛商业评论》,挑出来最有用的分享下

上次分享过一个工具&#xff1a;一键批量下载公众号历史消息&#xff08;后台回复001获取&#xff09;。我把《哈佛商业评论》的历史文章&#xff0c;全部爬了下来。该杂志被全球商业誉为“管理圣经”。我最感兴趣的一部分是&#xff1a;个人管理。先搜索关键词&#xff1a;&qu…

codeforces 732/D 二分

给出考试时间和考试需要准备的时间&#xff0c;问最早考完所有科目的时间 二分答案 NlogN 二分抄神犇的写法 感觉挺舒服的嘻嘻嘻 1 #include<bits/stdc.h>2 using namespace std;3 const int MAXN1e55;4 int N,M,d[MAXN],w[MAXN],cnt[MAXN];5 void read(int &x){6 …

网页版的svn怎样同步代码_学会使用Hdlbits网页版Verilog代码仿真验证平台

大家推荐一款网页版的 Verilog代码编辑仿真验证平台&#xff0c;这个平台是国外的一家开源FPGA学习网站&#xff0c;通过“https://hdlbits.01xz.net/wiki/Main_Page”地址链接进入网页&#xff0c;在该网页上可以进行Verilog代码的编写、综合&#xff0c;而且最后还能够仿真出…

Python的下载及安装

1、官网下载地址&#xff1a;https://www.python.org/downloads/ 2、python设置环境变量&#xff1a; 在系统变量里添加Python的安装位置 3、在cmd里输入python里即可转载于:https://www.cnblogs.com/fun0623/p/5257573.html

使用Apache ActiveMQ的JMS开发基础

去年是我尝试JMS的时候。 背后的想法和概念让我有些困惑&#xff0c;但是当我知道它的用途后&#xff0c;我很快就掌握了它。 在本文中&#xff0c;我将展示使用Apache ActiveMQ作为后端使用Java开发简单的生产者/消费者的基础。 让我们首先从概念开始&#xff0c;这是一个简单…

PLSQL 经常自动断开失去连接的解决过程

问题背景&#xff1a; 情况是这样的&#xff0c;很多开发同事的PLSQL上班时间开着8个小时&#xff0c;有时候他们出去抽烟后或者中午吃完饭&#xff0c;回来在PLSQL上面执行就报错无响应&#xff0c;然后卡住了半天动弹不了&#xff0c;非得重新登录plsql才生效&#xff0c;我猜…

使用Cobertura,JUnit,HSQLDB,JPA涵盖您的测试

你好&#xff01;你好吗&#xff1f; 今天让我们谈谈一个非常有用的工具&#xff0c;名为“ Cobertura”。 该框架与我们在另一篇文章中看到的Emma框架具有相同的功能。 Cobertura和Emma之间的主要区别在于Cobertura显示带有图形的简历页面。 如果要查看有关该主题的其他主题…

C# 基础知识总结

要学好C#&#xff0c;基础知识的重要性不言而喻&#xff0c;现将常用到的一些基础进行总结&#xff0c;总结如下&#xff1a; 01. 数据类型转换&#xff1a; 强制类型转换(Chart--> int): char crA; int i (int)(cr); 02. 委托/匿名函数/Lamda表达式&#xff1a; 委托是匿…

使用Jolokia和JMX进行客户端服务器监视

Java监视工具的选择非常广泛&#xff08;由Google提供的随机选择和顺序&#xff09;&#xff1a; javamelody 压力探头 JVisualVM 控制台 贾蒙 Java JMX Nagios插件不适用 此外&#xff0c;还有各种专用工具&#xff0c;例如ActiveMQ &#xff0c; JBoss &#xff0c; Qu…

图书管理系统数据字典_2. 结构化——数据字典

返回目录&#xff1a;Chilan Yuk&#xff1a;软件工程分析设计图库目录​zhuanlan.zhihu.com一、基本知识用于定义数据流和数据存储的结构&#xff0c;并给出构成所给的数据流和数据存储的各数据项的基本数据类型。数据字典中应该包括关于数据的如下信息一般信息&#xff08;名…

重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符

题目描述给你一个仅由大写英文字母组成的字符串&#xff0c;你可以将任意位置上的字符替换成另外的字符&#xff0c;总共可最多替换 k 次。在执行上述操作后&#xff0c;找到包含重复字母的最长子串的长度。示例1输入&#xff1a; s "ABAB", k 2 输出&#xff1a; …

python基础(一)简单入门

一.第一个python程序 1.交互式编程 直接在命令行里面输入python即可进入python交互式命令行&#xff0c;linux下一样&#xff1a; 在 python 提示符中输入以下文本信息&#xff0c;然后按 Enter 键查看运行效果&#xff1a; 2.脚本式编程 把代码都写到文件里面&#xff0c;然后…