title: Downloading large files in ASP.NET Core 2.1
body: <p>I am working on an ASP.NET Core 2.1 API project, which will be consumed by an Angular App, and later on a mobile app. one of the required functionality is to zip and download a collection of files, the result zipped file is going to be large (1GB or more).
  the code I have now is working as follows:</p>
  <ol>
  <li>the Angular app requests the API and expects a blob response.</li>
  <li>the API on the server creates a Zip file and reads it using memory stream.</li>
  <li>the API returns the memory stream using File response.</li>
  <li>the method that subscribes to the download service in Angular saves
  the file.</li>
  </ol>
  <p>what is happening now is when I click in the browser on the download button I have to wait for the download to be finished then the browser shows the default popup that allows the user to save and select where to save.</p>
  <p><strong>I was wondering if what I'm doing is correct and won't cause any memory problems in the future?</strong></p>
  <p><strong>is there a better methodology where the file could be streamed smoothly, so when the download starts the browser directly shows the save message and shows the default browser progress bar?</strong></p>
  <p>angular code:</p>
  <p>component click function:</p>
  <pre><code>download(event,id){
      event.stopPropagation();
      event.preventDefault();
      
      this.myservice.Downloadservice(avatar_id).subscribe((res: any) =&gt; {
      
        saveAs(res.data, res.filename); 
      });
    }
  </code></pre>
  <p>service code:</p>
  <pre><code>DownloadAllservice(id): Observable&lt;any&gt; {
      let authToken = localStorage.getItem('auth_token');
      let _options = { headers: new Headers({ 'Authorization': `Bearer ${authToken}`, } ),responseType: ResponseContentType.Blob };
      let formData = new FormData();
      let options ={
        type: &quot;zip&quot;,
        id: id
      };
      formData.append('options',JSON.stringify(options));
      
      return this.http.post(this.baseUrl + &quot;/api/Download/&quot;, formData, _options)
        .map(response =&gt;{
       
         return {
            'filename': this.getFileNameFromHttpResponse(response),
           'data': response.blob()
        } })
        .catch(this.handleError);
    }
  </code></pre>
  <p>.net core code:</p>
  <pre><code>[Authorize(Policy = &quot;Admin&quot;)]
          [DisableRequestSizeLimit]
          [HttpPost(&quot;Download&quot;, Name = &quot;Download&quot;)]
          public async Task&lt;IActionResult&gt; Download()
          {
              // get files list then start creating the temp folder and zipped folder
  
  
  
              var archive = Path.Combine(Directory.GetDirectoryRoot(&quot;wwwroot&quot;), @&quot;home\&quot; + FilePath + @&quot;\temp\&quot; + &quot;filename&quot;);
              var temp = Path.Combine(Directory.GetDirectoryRoot(&quot;wwwroot&quot;), @&quot;home\&quot; + FilePath + @&quot;\temp&quot;);
              if (!System.IO.Directory.Exists(temp))
              {
                  Directory.CreateDirectory(temp);
              }
             
                 
                  Directory.CreateDirectory(archive);
  
              try
              {
                 
                  foreach (var file_id in filelist)
                  {
                     
                      var path = file.path;
                      if (!System.IO.File.Exists(Path.Combine(archive, Path.GetFileName(path)))) {
                          System.IO.File.Copy(path, Path.Combine(archive, Path.GetFileName(path)));
                      }
                      
  
                  }
                
                  var archivezip = Path.Combine(Directory.GetDirectoryRoot(&quot;wwwroot&quot;), @&quot;home\&quot; + FilePath + @&quot;\temp\&quot; + &quot;filename&quot; + &quot;.zip&quot;);
  
                  // create a new archive
                  ZipFile.CreateFromDirectory(archive, archivezip);
                 
                  var memory = new MemoryStream();
  
                  using (var stream = new FileStream(archivezip, FileMode.Open))
                  {
                      await stream.CopyToAsync(memory);
                  }
                  memory.Position = 0;
                  Directory.EnumerateFiles(archive).ToList().ForEach(f =&gt; System.IO.File.Delete(f));
                  Directory.EnumerateDirectories(archive).ToList().ForEach(f =&gt; System.IO.Directory.Delete(f, true));
                  Directory.Delete(archive);
                  System.IO.File.Delete(archivezip);
                  return File(memory, &quot;application/octet-stream&quot;,&quot;filename.zip&quot;);
  
              }
              catch (Exception ex)
              {
  
                  return new BadRequestObjectResult(ex.Message);
              }
          }
  </code></pre>
  <p>please note that in the future not only angular app will use the API, but mobile apps will also be added</p>