從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.pswp.cn/news/373535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373535.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373535.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

0. 洗好蝦和鍋 1. 放水放老姜,燒開,放鹽 2. 放入蝦,沸騰后,嘗咸淡 3. 放香蔥,乘起來轉載于:https://www.cnblogs.com/gary-tao/p/5248139.html

讀字庫遇到坑爹的問題

轉載請注明出處:http://blog.csdn.net/qq_26093511/article/details/53099262 最近在做一個led顯示屏的項目, 我想顯示 “常”,“州”,“大”,“學”這幾個字,但是只能顯示 “常” 和 “大”,…

如果–否則為編碼風格最佳實踐

下面的帖子將是一個高級花括號討論,沒有對與錯的答案,只是更多的“品味”。 它是關于是否將“ else”(以及其他關鍵字,例如“ catch”,“ finally”)放在換行符上。 有些人可能會寫 if (something) {doIt(…

MongoDB 去重(distinct)查詢后求總數(count)

在使用MonoDB 做報表匯總經常的有去重統計總數的需求,在此總結一下實現方式: 1, 直接使用distinct 語句查詢, 這種查詢會將所有查詢出來的數據返回給用戶, 然后對查詢出來的結果集求總數(耗內存,耗時一些) var len db.student.distinct("name",{"age" :…

adobe premiere pro cc2015.0已停止工作 解決辦法

adobe premiere pro cc2015.0已停止工作 一直報錯 解決辦法就是: 刪除【我的電腦】- 【我的文檔】下的 Adobe 下的Premiere Pro文件夾 現象就是怎么重新安裝都不管用Premiere 參考路徑 :C:\Users\xxx\Documents\Adobe\Premiere Pro 轉載于:https://…

java mysql 語句解析器_幾種基于Java的SQL解析工具的比較與調用

1、sqlparserhttp://www.sqlparser.com/優點:支持的數據庫最多,除了傳統數據庫外還支持hive和greenplum一類比較新的數據庫,調用比較方便,功能不錯缺點:收費,500$起2、Apache Calcite一個構建JDBC或者ODBC訪…

Css Sprites 多張圖片整合在一張圖片上

CSS Sprites原理: CSS Sprites其實就是把網頁中一些背景圖片整合到一張圖片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的組合進行背景定位,background-position可以用數…

MongoDB 分析查詢性能

cursor.explain(“executionStats”)和 db.collection.explain(“executionStats”) 方法提供關于查詢性能的相關信息。這些信息可用于衡量查詢是否使用了索引以及如何使用索引。 db.collection.explain() 還提供有關其他操作的執行信息。例如 db.collection.update()。 有關詳…

無需復雜插件即可從Eclipse啟動和調試Tomcat

像Eclipse這樣的現代IDE提供了各種插件來簡化Web開發。 但是,我相信將Tomcat作為“常規” Java應用程序啟動仍然可以提供最佳的調試體驗。 大多數情況下,這是因為這些工具將Tomcat或任何其他servlet容器作為外部進程啟動,然后在其上附加一個遠…

flutter 國際化_Flutter 開發實戰資源推薦

開工第一天,來點輕松的資源推薦。這是一篇實戰類資源推薦,其實Flutter的入門資料官方已經做得很好了,如果你是零基礎,還是建議先啃一遍官方的教程,然后再看以下實戰資源,相信在你看官方課程中涉及到的一些疑…

2-5-666:放蘋果

描述把M個同樣的蘋果放在N個同樣的盤子里,允許有的盤子空著不放,問共有多少種不同的分法?(用K表示)5,1,1和1,5,1 是同一種分法。輸入第一行是測試數據的數目t&#xff08…

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 …

php mysql 線程安全_PHP 線程安全與非線程安全版本的區別深入解析

從2000年10月20日發布的第一個Windows版的PHP3.0.17開始的都是線程安全的版本&#xff0c;這是由于與Linux/Unix系統是采用多進程的工作方式不同的是Windows系統是采用多線程的工作方式。如果在IIS下以CGI方式運行PHP會非常慢&#xff0c;這是由于CGI模式是建立在多進程的基礎之…

奶牛健美操(codevs 3279)

題目描述 Description Farmer John為了保持奶牛們的健康&#xff0c;讓可憐的奶牛們不停在牧場之間 的小路上奔跑。這些奶牛的路徑集合可以被表示成一個點集和一些連接 兩個頂點的雙向路&#xff0c;使得每對點之間恰好有一條簡單路徑。簡單的說來&#xff0c; 這些點的布局就是…

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…

數據結構之楊氏矩陣

轉自&#xff1a; http://blog.csdn.net/jiyanfeng1/article/details/8189228轉載于:https://www.cnblogs.com/neversayno/p/5256262.html

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…

使用jdk壓縮war包

首先安裝jdk 壓縮 ..../jdk/bin/jar -cvf file.war file 解壓 ..../jdk/bin/jar -xvf file.war 轉載于:https://www.cnblogs.com/chongchong88/p/6049690.html