2011-02-14 2 views
60

Я разрабатываю веб-приложение с mongodb как мой back-end. Я бы хотел, чтобы пользователи загружали изображения в свои профили, например, в виде связанного профиля. Я использую страницу aspx с MVC2, и я читал, что библиотека GridFs используется для хранения больших типов файлов в качестве двоичных файлов. Я везде искал подсказки, как это делается, но у mongodb нет документации для C# api или GridFs C#. Я озадачен и смущен, могу действительно использовать другой набор мозгов.MongoDB GridFs с C#, как хранить файлы, такие как изображения?

Кто-нибудь знает, как реально реализовать контроллер загрузки файлов, который хранит изображение, загруженное пользователем в коллекцию mongodb? Бесконечно благодарен!

Я пробовал варианты этого безрезультатно.

Database db = mongo.getDB("Blog"); 
GridFile file = new GridFile(db); 
file.Create("image.jpg"); 

var images = db.GetCollection("images"); 
images.Insert(file.ToDocument()); 
+0

https: // stackoverflow.com/questions/45535296/how-to-create-a-cdn-server-in-dotnet-core-using-mongodb-gridfs-and-angularjs?noredirect1_comment78034138_45535296 –

ответ

84

Следующий пример показывают, как сохранить файл и читать обратно из gridfs (используя официальный драйвер MongoDB):

var server = MongoServer.Create("mongodb://localhost:27020"); 
var database = server.GetDatabase("tesdb"); 

var fileName = "D:\\Untitled.png"; 
var newFileName = "D:\\new_Untitled.png"; 
using (var fs = new FileStream(fileName, FileMode.Open)) 
{ 
    var gridFsInfo = database.GridFS.Upload(fs, fileName); 
    var fileId = gridFsInfo.Id; 

    ObjectId oid= new ObjectId(fileId); 
    var file = database.GridFS.FindOne(Query.EQ("_id", oid)); 

    using (var stream = file.OpenRead()) 
    { 
     var bytes = new byte[stream.Length]; 
     stream.Read(bytes, 0, (int)stream.Length); 
     using(var newFs = new FileStream(newFileName, FileMode.Create)) 
     { 
     newFs.Write(bytes, 0, bytes.Length); 
     } 
    } 
} 

Результаты:

Файл:

File im mongodb

Chunks Коллекция:

Chunks collection

Надеется, что это поможет.

+1

Andrew, что вы используете для просмотра результат? Какая программа - скриншоты? Выглядит alite lite sql manager. – Goff

+8

@ Goff: Это монгову -> http://www.mongovue.com/. –

+0

Andrew, один вопрос, поскольку MongoDb разбивает большие файлы на более мелкие куски для хранения, может ли он использоваться для частичного хранения и возобновления позже? Скажем, кто-то пишет приложение Cloud Cloud Backup в MongoDB, где файлы автоматически резервируются. Теперь предположим, что файл PDF резервную копию, когда 70% файла завершил резервное копирование (я говорю на языке копирования файлов в ОС, скажем, когда мы копируем файл с одного диска на другой в Windows, '60 % done '), пользователь отключается. Когда он снова подключится, может ли 70% -ная информация использоваться для возобновления резервного копирования с того места, где она была остановлена. – SexyBeast

17

Этот пример позволит вам связать документ с объектом

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using MongoDB.Driver; 
using MongoDB.Driver.Linq; 
using MongoDB.Bson; 
using MongoDB.Driver.Builders; 
using MongoDB.Driver.GridFS; 
using System.IO; 

namespace ConsoleApplication1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     MongoServer ms = MongoServer.Create(); 
     string _dbName = "docs"; 

     MongoDatabase md = ms.GetDatabase(_dbName); 
     if (!md.CollectionExists(_dbName)) 
     { 
      md.CreateCollection(_dbName); 
     } 

     MongoCollection<Doc> _documents = md.GetCollection<Doc>(_dbName); 
     _documents.RemoveAll(); 
     //add file to GridFS 

     MongoGridFS gfs = new MongoGridFS(md); 
     MongoGridFSFileInfo gfsi = gfs.Upload(@"c:\mongodb.rtf"); 
     _documents.Insert(new Doc() 
     { 
      DocId = gfsi.Id.AsObjectId, 
      DocName = @"c:\foo.rtf" 
     } 
     ); 

     foreach (Doc item in _documents.FindAll()) 
     { 
      ObjectId _documentid = new ObjectId(item.DocId.ToString()); 
      MongoGridFSFileInfo _fileInfo = md.GridFS.FindOne(Query.EQ("_id", _documentid)); 
      gfs.Download(item.DocName, _fileInfo); 
      Console.WriteLine("Downloaded {0}", item.DocName); 
      Console.WriteLine("DocName {0} dowloaded", item.DocName); 
     } 

     Console.ReadKey(); 
    } 
} 

class Doc 
{ 
    public ObjectId Id { get; set; } 
    public string DocName { get; set; } 
    public ObjectId DocId { get; set; } 
} 
14

Ответы выше вскоре будут устаревшими теперь, что 2,1 RC-0 водитель был освобожден.

Способ работы с файлами в v2.1 MongoDB с GridFS теперь может быть сделано таким образом:

using MongoDB.Bson; 
using MongoDB.Driver; 
using MongoDB.Driver.GridFS; 
using System.IO; 
using System.Threading.Tasks; 

namespace MongoGridFSTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var client = new MongoClient("mongodb://localhost"); 
      var database = client.GetDatabase("TestDB"); 
      var fs = new GridFSBucket(database); 

      var id = UploadFile(fs); 

      DownloadFile(fs, id); 
     } 

     private static ObjectId UploadFile(GridFSBucket fs) 
     { 
      using (var s = File.OpenRead(@"c:\temp\test.txt")) 
      { 
       var t = Task.Run<ObjectId>(() => { return 
        fs.UploadFromStreamAsync("test.txt", s); 
       }); 

       return t.Result; 
      } 
     } 

     private static void DownloadFile(GridFSBucket fs, ObjectId id) 
     { 
      //This works 
      var t = fs.DownloadAsBytesByNameAsync("test.txt"); 
      Task.WaitAll(t); 
      var bytes = t.Result; 


      //This blows chunks (I think it's a driver bug, I'm using 2.1 RC-0) 
      var x = fs.DownloadAsBytesAsync(id); 
      Task.WaitAll(x); 
     } 
    } 
} 

Это берется из дифф на C# драйвер тестов here

+0

Я не пробовал код. Это работает? Вы сказали, что это дули куски –

+0

Хороший вопрос. Чтобы уточнить, первый вызов DownloadAsBytesByNameAsync работает отлично. Второй вызов терпит неудачу. Но было предложено изменение, которое показало, что для того, чтобы DownloadAsBytesAsync работал с нулевым аргументом CancellationToken, должен быть включен, а не null. – Josh

+0

Thx для ответа. Существуют ли синхронные методы загрузки файлов? –

 Смежные вопросы

  • Нет связанных вопросов^_^