1

I would like to get the File and pass it as stream but I'm not sure how to do this. I do have a path where the file is located. So basically using this path I'm going to retrieve this file and save it as stream. But correct me if I'm wrong, but is it correct to assume that "Reading as Stream" is something like it's actually opening the file and reading it?

Are there anyway to just retrieve or Copy the file into a FileStream or MemoryStream? Right now I have this but not sure if this is correct

 foreach (string filePath in filePaths)
 {
      string filename = Path.GetFileName(filePath);
      //Constants.Conventions.MediaTypes.Image
      string mediaType = Constants.Conventions.MediaTypes.File;
      string ext = Path.GetExtension(filename);
      IMedia media = Services.MediaService.CreateMedia(filename, Constants.System.Root, mediaType);
      MemoryStream ms = new MemoryStream();
      using (Stream stream = System.IO.File.OpenRead(filePath))
      {
           ms.WriteTo(stream);
      }
      media.SetValue("umbracoFile", filename, ms);
      // Save the media
      Services.MediaService.Save(media);
      media = null;
      System.IO.File.Delete(filePath);
 }

I'm not so sure if this is the best approach. But the main goal is to retrieve that file from the path and save it in media.SetValue("umbracoFile", filename, ms); as it's requiring a Stream as input. How do I do this in a most efficient way? I'm always getting outofmemoryexception due to large file. So I'm guessing because it's reading it as Stream that it's throwing an error on large file. So maybe we can just copy it to save. I'm not so sure really needs help here

Update: Here is the config to make sure I don't run out of memory

<httpRuntime requestValidationMode="2.0" enableVersionHeader="false" maxRequestLength="2097151" executionTimeout="50000000" targetFramework="4.5" fcnMode="Single" />

<location path="umbraco">
  <system.web>
    <httpRuntime maxRequestLength="204800" executionTimeout="99999"/>
  </system.web>
</location>

<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="2294967295" />
  </requestFiltering>
</security>

And this is the build of my project

enter image description here

enter image description here

enter image description here

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
MadzQuestioning
  • 3,341
  • 8
  • 45
  • 76
  • Are you compiling your app for 64 bits? That will increase a lot the quantity of memory you can use. – Gusman Jun 27 '20 at 10:09
  • Yeah already did – MadzQuestioning Jun 27 '20 at 10:33
  • Beware that .net has a very stupid option "prefer 32 bits" in the compilation properties, if it's enabled even if you compile it for x64 it will run the program in 32 bits mode. Also, if this is running under IIS check it's executing in 64 bit mode. – Gusman Jun 27 '20 at 10:41
  • @Gusman can you check if my settings are correct? I basically changed it to x64 but I'm still getting an OutOfMemoryException error when processing 1.6GB of file – MadzQuestioning Jun 27 '20 at 10:48
  • Yes, it seems you have everything configured ok... – Gusman Jun 27 '20 at 11:13
  • I can't even upload files that are 1.4GB in size.. I thought I can upload it since the limit should be 2gb – MadzQuestioning Jun 27 '20 at 11:20
  • Check this, it may help: https://stackoverflow.com/questions/8563933/c-sharp-out-of-memory-exception/20912869#20912869 – Gusman Jun 27 '20 at 11:27

2 Answers2

1

You could try something like the code below and save yourself the trouble of opening it and then converting to a memory stream by using FileStream.

foreach (string filePath in filePaths)
{
    string filename = Path.GetFileName(filePath);
    string mediaType = Constants.Conventions.MediaTypes.File;
    string ext = Path.GetExtension(filename);
    IMedia media = Services.MediaService.CreateMedia(filename, Constants.System.Root, mediaType);
    using (var fs = new FileStream(filePath, FileMode.Open))
    {
        media.SetValue("umbracoFile", filename, fs);
        Services.MediaService.Save(media);
    }

    media = null;
    System.IO.File.Delete(filePath);
}
Shoejep
  • 4,414
  • 4
  • 22
  • 26
1

You can simply copy FileStream to MemoryStream in .Net Framework 4+

MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    file.CopyTo(ms);
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • Sorry for the noob question but what are the benefit of Copyig the Filestream into MemoryStream? Will this somehow solve any out of memory exception issue? – MadzQuestioning Jun 27 '20 at 09:15
  • @MadzQuestioning try it once, is it solving your issue? – Vivek Nuna Jun 27 '20 at 09:25
  • When debugging it's actually a more process when viewing in debugging and a split seconds delay compared to @Shoejep suggestion and it didn't solve my problem I'm still getting a OutOfMemoryException – MadzQuestioning Jun 27 '20 at 10:02