thephpleague / flysystem

Abstraction for local and remote filesystems
https://flysystem.thephpleague.com
MIT License
13.37k stars 831 forks source link

Copy Directory #234

Closed newtonianb closed 10 years ago

newtonianb commented 10 years ago

How can I copy a directory from sourcePath to targetPath ?

frankdejonge commented 10 years ago

This should be done in user land code. A default implementation would make to many assumptions. You'd need to use a combination of listContents and copy (for files) and createDir (for directories).

frankdejonge commented 10 years ago

The implementation for copyDirectory across adapters would have more to do with listContents and readStream + writeStream.

kachkaev commented 9 years ago

Why can't there be a plugin that does it? I'm asking because this seems like a pretty common task. I don't quite understand the complexity of the assumptions, to be honest. One recursive function + one caller method.

Maybe the complications may arise with large hierarchies or file sizes – I don't have much experience with these cases. @frankdejonge, could you please explain?

Searching "flysystem copy directory" points to this page first, so this is probably the best place for a discussion.

I'd like to do something like that at the moment: $mountManager->copyDir('zipfs://source/dir', 'localfs://target/dir');

UPD: Ah! The complications may come from the default action for files that are already in the target directory. Maybe copyDir is not the best name for the method then. How about rsync with a simpler behaviour?

maximelebastard commented 8 years ago

+1

bkuhl commented 8 years ago

if copy doesn't support both files and directories it should probably renamed to the more explicit copyFile().

symball commented 8 years ago

+1 for this request; would make OneUp incrediby powerful. Similar to Kachkaev, i'm wanting to go from zipfs to S3.

symball commented 8 years ago

In the meantime, for any pondering a quick way of performing this. In the example:

   $contents = $mountManager->listContents('scratch://'.$publication->getSlug(), true);
   foreach ($contents as $fileNode)
   {
       if($fileNode['type'] == 'dir')
       {
           $mountManager->createDir('s3://'.$fileNode['path']);
           continue;
       }

       $mountManager->put(
           's3://'.$fileNode['path'],
           $mountManager->read('scratch://'.$fileNode['path'])
       );
   }
bkuhl commented 8 years ago

Not the ideal approach, but the S3 package supports uploading a directory under the covers:

        $s3Client = app('s3Client');
        $this->s3Client->uploadDirectory(
            $localDirectory,
            $awsBucket,
            $pathPrefixInAWS,
            $awsOptions
        );
leith commented 8 years ago

@symball Would you need to use createDir() when they would be created implicitly by wrapping the put() in a $fileNode['type'] == 'file' (or != 'dir') check? Unless of course you really need those empty directories...

symball commented 8 years ago

For my usage, the above was something I put together very quickly and it is looping through a huge list of files. at the time thought it wouldn't hurt to simply have directories created, it is supposed to be copying from one filesystem to another so missing even empty directories breaks that.

deepak1725 commented 6 years ago

For Guys still having this Issue. please refer https://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-transfer.html

rulatir commented 3 years ago

For Guys still having this Issue. please refer https://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-transfer.html

This issue is not s3 specific.