2017-12-20 4 views
0

Ich verwende PortableWebDavLibrary, um eine Verbindung zur nextcloud WebDAV API herzustellen. https://github.com/DecaTec/Portable-WebDAV-LibraryDatei von einer anderen API herunterladen und diese mit Puffer zurückgeben

Meine einfache Steuerung

// GET api/download/Test/pedro.txt 
    [HttpGet("{*name}")] 
    public async Task<IActionResult> Get(string name) 
    { 
     if (String.IsNullOrEmpty(name)) 
     { 
      return BadRequest("TEXT ..."); 
     } 
     try 
     { 
      var credentials = new NetworkCredential("USER", "PASS"); 
      using (var webDavSession = new WebDavSession(Global.BASE_URL, credentials)) 
      { 
       var stream = new MemoryStream(); 
       stream.SetLength(20971520); // TEST set max size 

       var responseStream = await webDavSession.DownloadFileAsync(name, stream); 

       stream.Seek(0, SeekOrigin.Begin); 

       // Response.Headers.Add("content-disposition", "attachment; filename=" + name.TrimEnd('/').Split("/").Last()); 
       return new FileStreamResult(stream, new MediaTypeHeaderValue("application/octet-stream")) 
       { 
        FileDownloadName = name.TrimEnd('/').Split("/").Last() 
       }; 


      } 
     } 
     catch (Exception e) 
     { 
      return BadRequest("TEXT ..."); 
     } 

Die Datei heruntergeladen wird, aber bevor die Datei im Speicher (Memorystream) und die Erinnerung an der geht in größten Dateien bis zu mehr als 2/3 GB sparen.

Wie kann ich herunterladen, während ich die Datei von der anderen API bekomme? ähnlich einem Puffer

Edited 31.12.2017

Nextcloud Download einer Datei mit einer GET-Anfrage ermöglichen (ohne webdav), mit diesem der Filestreamresult arbeiten gut.

Antwort

0

Ja, Ihre Lösung mit MemoryStream wird nicht gut für große Dateien funktionieren. Man könnte es beheben, indem Sie heruntergeladene Inhalte zu einer temporären Datei zu speichern und es dann den Upload:

var tempFileName = Path.GetTempFileName(); 
var stream = new FileStream(tempFileName, FileMode.Create); 
await webDavSession.DownloadFileAsync(name, stream); 

stream.Seek(0, SeekOrigin.Begin); 
return new FileStreamResult(stream, new MediaTypeHeaderValue("application/octet-stream")) 
{ 
    FileDownloadName = name.TrimEnd('/').Split("/").Last() 
}; 

Das Problem mit diesem Code ist, dass es temporäre Dateien auf dem Server verläßt. GetTempFileName() wird schließlich IOException werfen, wenn die Anzahl der temporären Dateien 65535 erreicht. Um dies zu beheben, müssen Sie regelmäßig alte temporäre Dateien entweder in Ihrer Controller-Aktion oder in einer separaten Server-Task löschen.

+0

Vielen Dank für die Antwort, ist es nicht möglich, schreiben Sie die Datei in Temp-Ordner und gleichzeitig senden Sie ihn und nicht warten, um alle Datei zu lesen? – erni

+0

Es gibt einen 'PushStreamContent' in' System.Net.Http' genau für diesen Zweck. Leider gibt es nichts Ähnliches in .Net Core für diesen Moment :( – CodeFuller

0

Es ist unwahrscheinlich, dass Sie tun können, was Sie fragen, wie wird die stream die Informationen, die Sie brauchen halten gehen nach der Aufruf von DownloadFileAsync erfolgreich zurückgekehrt ist. Daher senden Sie nichts, bevor dies geschieht, nicht korrekt.

Verwandte Themen