使用s3fs.put递归复制文件夹到S3时的行为不一致问题
解决s3fs递归上传本地文件夹到S3的行为不一致问题
问题原因
s3fs的put(recursive=True)行为会根据目标S3路径是否存在产生差异:
- 当目标路径不存在时,会将源文件夹内部的所有内容直接写入目标路径
- 当目标路径已存在时,会将源文件夹本身作为子目录写入目标路径,导致出现额外层级(比如你遇到的
baz/bar/...结构)
解决方案
要让上传行为始终一致,无论目标路径是否存在,都将源文件夹内的内容直接写入目标路径,有两种可靠方法:
方法1:修改源路径匹配文件夹内所有内容
将源路径改为foo/bar/*,明确指定上传bar目录下的所有内容,而非目录本身:
import s3fs source_path = 'foo/bar/*' target_path = 's3://my_bucket/baz' s3 = s3fs.S3FileSystem(anon=False) s3.put(source_path, target_path, recursive=True)
方法2:使用s3.cp并给源路径加末尾斜杠
s3.cp的行为更贴近传统shell的cp -r,给源路径加上末尾/,表示复制目录内的内容而非目录本身,无论目标是否存在,行为完全一致:
import s3fs source_path = 'foo/bar/' target_path = 's3://my_bucket/baz/' s3 = s3fs.S3FileSystem(anon=False) s3.cp(source_path, target_path, recursive=True)
注意事项
- 你之前给
target_path加斜杠无效,是因为问题根源在源路径的写法,而非目标路径 - 两种方法都能避免目标路径中出现额外的
bar目录,确保每次上传的结构都是S3://my_bucket/baz/<files and subfolders>
内容的提问来源于stack exchange,提问作者Pepacz
相关产品推荐
相关产品推荐

