title: Laravel 5 file downloads: stream() or download()
body: <p>I have a Laravel 5.4 app where authenticated users need to be able to download private files from S3 storage. I've setup a route and controller to allow private file downloads. </p>
  
  <p>The code looks like this:</p>
  
  <p>Route:</p>
  
  <pre><code>Route::get('file/{filename}', 'FileController@download')-&gt;where(['filename' =&gt; '[A-Za-z0-9-._\/]+'])-&gt;name('file')-&gt;middleware('auth:employee');
  </code></pre>
  
  <p>Controller:</p>
  
  <pre><code>public function download($fileName)
  {
      if (!$fileName || !Storage::exists($fileName)) {
          abort(404);
      }
  
      return response()-&gt;stream(function() use ($fileName) {
          $stream = Storage::readStream($fileName);
          fpassthru($stream);
          if (is_resource($stream)) {
              fclose($stream);
          }
      }, 200, [
          'Cache-Control'         =&gt; 'must-revalidate, post-check=0, pre-check=0',
          'Content-Type'          =&gt; Storage::mimeType($fileName),
          'Content-Length'        =&gt; Storage::size($fileName),
          'Content-Disposition'   =&gt; 'attachment; filename="' . basename($fileName) . '"',
          'Pragma'                =&gt; 'public',
      ]);
  }
  </code></pre>
  
  <p>All working fine, but when I had a closer look to the <a href="https://laravel.com/docs/5.4/responses#file-downloads" rel="noreferrer">Laravel docs</a>, I found that they just talk about <code>response()-&gt;download()</code>. </p>
  
  <p>If I implement that kind of response, my code would look like this:</p>
  
  <pre><code>public function download($fileName)
  {
      if (!$fileName || !Storage::exists($fileName)) {
          abort(404);
      }
  
      $file = Storage::get($fileName);
  
      return response()-&gt;download($file, $fileName, [
          'Content-Type'  =&gt; Storage::mimeType($fileName),
      ]);
  }
  </code></pre>
  
  <p>Both functions can be found in the <a href="https://laravel.com/api/5.4/Illuminate/Routing/ResponseFactory.html#method_stream" rel="noreferrer">API docs</a>.</p>
  
  <p>My question: what would be the preferred way to go and what are the advantages/disadvantages of each?</p>
  
  <p>From what I've gathered so far:</p>
  
  <p><strong>Stream:</strong></p>
  
  <ul>
  <li>Does not require the whole file to be loaded into memory</li>
  <li>Suitable for large files</li>
  </ul>
  
  <p><strong>Download:</strong></p>
  
  <ul>
  <li>Requires less code</li>
  </ul>