如何让dbutils.fs.cp实现与*nix cp相同的递归复制行为?
问题描述
在*nix系统中执行以下命令:
mkdir -p a/1 mkdir -p b/2 cp -r b a/
执行后通过tree a查看目录结构,结果如下:
a ├── 1 └── b └── 2
尝试使用Databricks的dbutils.fs执行相同操作:
dbutils.fs.mkdirs('dbfs:/tmp/a/1') dbutils.fs.mkdirs('dbfs:/tmp/b/2') dbutils.fs.cp( 'dbfs:/tmp/b', 'dbfs:/tmp/a/', True) dbutils.fs.ls('dbfs:/tmp/a')
但得到的结果是:
[FileInfo(path='dbfs:/tmp/a/1/', name='1/', size=0, modificationTime=1670871337000), FileInfo(path='dbfs:/tmp/a/2/', name='2/', size=0, modificationTime=1670871337000)]
如何让dbutils.fs.cp实现与*nix系统中cp -r相同的行为?
解决方法
核心差异在于两者的路径处理逻辑:
- *nix下的
cp -r b a/会将整个b目录复制到a目录下,最终形成a/b/2的层级结构 - 而
dbutils.fs.cp如果目标路径是已存在的目录,会直接将源目录内的所有内容复制到目标目录中,而非复制源目录本身
要实现一致效果,只需修改cp的目标路径,明确指定要创建的目标目录名(即把目标路径从dbfs:/tmp/a/改为dbfs:/tmp/a/b):
dbutils.fs.mkdirs('dbfs:/tmp/a/1') dbutils.fs.mkdirs('dbfs:/tmp/b/2') # 明确指定目标路径为 dbfs:/tmp/a/b,将整个b目录复制到a下 dbutils.fs.cp( 'dbfs:/tmp/b', 'dbfs:/tmp/a/b', True) dbutils.fs.ls('dbfs:/tmp/a')
执行后查看dbfs:/tmp/a的内容,就能得到与*nix一致的结果:
[FileInfo(path='dbfs:/tmp/a/1/', name='1/', size=0, modificationTime=xxx), FileInfo(path='dbfs:/tmp/a/b/', name='b/', size=0, modificationTime=xxx)]
注:dbutils.fs.cp在递归模式(第三个参数为True)下会自动创建不存在的父目录,无需手动提前创建目标目录的父路径。
内容的提问来源于stack exchange,提问作者Chris Snow
相关产品推荐
相关产品推荐

