4

I have two disks defined in my filesystems.php config file:

'd1' => [
    'driver' => 'local',
    'root' => storage_path('app/d1'),
],
'd2' => [
   'driver' => 'local',
   'root' => storage_path('app/d2'),
],

These disk could also be Amazon S3 buckets, and there could be combination of S3 bucket and a local disk.

Let's say I have a file as app/d1/myfile.txt which I want to move to app/d2/myfile.txt.

What I'm doing now is

$f = 'myfile.txt';
$file = Storage::disk('d1')->get($f);
Storage::disk('d2')->put($f, $file);

and leaving the original file on d1 as it doesn't bother me (I periodically delete files from d1).

My questions are:

Is the code below atomic, how would I check if it was, and if not how would I make it atomic (for the scenarios when the files are 1GB or something similar in size):

$f = 'myfile.txt';
$file = Storage::disk('d1')->get($f);
Storage::disk('d2')->put($f, $file);
Storage::disk('d1')->delete($f);

Is there a simple way to move files from one disk to another using the Storage facade. At the moment I need it to work from one local disk to another but in the future I might need to move them from one S3 bucket to the same one, from one S3 bucket to another one, or from local disk to a S3 bucket.

Thanks

brnd0
  • 338
  • 6
  • 15

2 Answers2

5

I think this way is cleaner and works if you're using remote paths

    $directories = ['dir1', 'dir2', 'dir3'];
    $from = 'public';
    $to = 'assets';

    foreach($directories as $directory){
        $files = Storage::disk($from)->allFiles($directory);

        foreach ($files as $file) {

            Storage::disk($to)->writeStream($file, Storage::disk($from)->readStream($file));

            // If you no longer need the originals
            //Storage::disk($from)->delete($file);
        }

        Storage::disk($from)->deleteDirectory($directory);
    }
ahackney
  • 534
  • 6
  • 14
2

The move method may be used to rename or move an existing file to a new location.

Storage::move('old/file.jpg', 'new/file.jpg');

However, to do this between disks you need to have the full path to the file to move.

    // convert to full paths
    $pathSource = Storage::disk($sourceDisk)->getDriver()->getAdapter()->applyPathPrefix($sourceFile);
    $destinationPath = Storage::disk($destDisk)->getDriver()->getAdapter()->applyPathPrefix($destFile);

    // make destination folder
    if (!File::exists(dirname($destinationPath))) {
        File::makeDirectory(dirname($destinationPath), null, true);
    }

    File::move($pathSource, $destinationPath);
MrEduar
  • 1,784
  • 10
  • 22