2011-02-14 8 views
60

Zajmuję się tworzeniem aplikacji internetowej z mongodb jako moim back-endem. Chciałbym, aby użytkownicy przesłali zdjęcia do swoich profili, tak jak połączone zdjęcie profilowe. Używam strony aspx z MVC2 i czytam, że biblioteka GridFs służy do przechowywania dużych plików jako plików binarnych. Szukałem wszędzie wskazówek jak to się robi, ale mongodb nie ma żadnej dokumentacji dla C# api lub GridFs C#. Jestem zdezorientowany i zdezorientowany, naprawdę mogę użyć innego zestawu mózgów.MongoDB GridFs z C#, jak przechowywać pliki takie jak obrazy?

Ktoś wie, jak zaimplementować kontroler przesyłania plików, który przechowuje obraz przesłany przez użytkownika do kolekcji mongodb? Stukrotne dzięki!

Próbowałem wariacji tego bez skutku.

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?noredirect=1#comment78034138_45535296 –

Odpowiedz

84

poniższym przykładzie pokazują, jak zapisać plik i odczytać z powrotem gridfs (używając oficjalnego kierowcę 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); 
     } 
    } 
} 

Wyniki:

Plik:

File im mongodb

Kawałki kolekcja:

Chunks collection

Nadzieja ta pomoc.

+1

Andrew, Do czego służysz do przeglądania wynik? Z jakiego programu pochodzą zrzuty ekranu? Wygląda na alot lite sql manager. – Goff

+8

@Goff: To mongovue -> http://www.mongovue.com/. –

+0

Andrew, jedno pytanie, ponieważ MongoDb dzieli duże pliki na mniejsze porcje do przechowywania, czy może być używane do częściowego przechowywania i wznowienia później? Powiedzmy, że ktoś pisze na komputerze MongoDB aplikację do tworzenia kopii zapasowych na komputer stacjonarny, na której automatycznie tworzone są kopie zapasowe plików. Załóżmy teraz, że kopia zapasowa pliku PDF jest tworzona, gdy 70% pliku zakończyło tworzenie kopii zapasowej (mówię w skrócie o kopiowaniu plików w systemie operacyjnym, na przykład kiedy kopiujemy plik z jednego dysku na inny w systemie Windows, % wykonano "rodzaj wiadomości", użytkownik się rozłącza. Kiedy połączy się ponownie, czy 70% informacji będzie można użyć do wznowienia tworzenia kopii zapasowej od miejsca, w którym zostało przerwane. – SexyBeast

17

Przykład ten pozwala powiązać dokument do obiektu

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

powyższych odpowiedzi niebawem być nieaktualne już, że 2,1 RC-0 kierowca został zwolniony.

drodze do pracy z plikami w v2.1 MongoDB z GridFS można teraz zrobić w ten sposób:

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); 
     } 
    } 
} 

To jest wzięte z diff sprawie testów kierowcy C# here

+0

Nie próbowałem kodu. Czy to działa? Powiedziałeś, że to dmuchnęło w kawałki –

+0

Dobre pytanie. Aby wyjaśnić, pierwsze połączenie, DownloadAsBytesByNameAsync, działa dobrze. Drugie połączenie nie udaje się. Ale była sugerowana edycja, która pokazała, że ​​aby funkcja DownloadAsBytesAsync działała poprawnie, musi być włączony zerowy argument CancellationToken, a nie wartość null. – Josh

+0

Thx za odpowiedź. Czy istnieją synchroniczne metody pobierania plików do pobrania? –