Copiar ficheros de un disco a otro en Laravel

Cuando estamos trabajando con ficheros muy grandes, la llamada a `Storage::get($fileName)` va a producir un error porque PHP se queda sin memoria.

Copiar ficheros de un disco a otro en Laravel
Photo by Adam Winger / Unsplash

Como les comentaba en este post sobre guardar una respuesta HTTP a un fichero, estos días he estado trabajando en una aplicación data-intensive.

Otro de los problemas que tuve es que, para no ocupar mucho espacio en el disco actual (estamos hablando de muchos ficheros CSV que ocupan varios terabytes de datos), programé para que la descarga de dichos ficheros fuera directamente a Amazon S3.

Luego, a la hora de procesarlos, la idea era descargar los ficheros de uno en uno y, tras procesarlos, eliminarlos.

Normalmente, podríamos hacer un código así:

$s3 = Storage::disk('s3');
$local = Storage::disk('local');

$contents = $s3->get($fileName);
$local->put($fileName, $contents);

Sin embargo, cuando estamos trabajando con ficheros muy grandes, la llamada a $s3→get($fileName) va a producir un error porque PHP se queda sin memoria.

Copiar ficheros muy grandes de un disco a otro en Laravel

Este fue el problema que me encontré yo al trabajar en esto. Por suerte, la librería de Flysystem (la que usa Laravel en su sistema Storage) nos tiene las espaldas cubiertas permitiéndonos copiar y escribir a través del uso de streams:

$local = Storage::disk('local');
$s3 = Storage::disk('s3');
$local->writeStream($fileName, $s3->readStream($fileName));

Al ejecutar $s3→readStream($fileName) se comenzará la descarga y, mientras se van descargando los bytes se van escribiendo en el disco local.