Python 如何使用PySpark计算ADL中的目录大小?

Python 如何使用PySpark计算ADL中的目录大小?,python,apache-spark,pyspark,databricks,azure-databricks,Python,Apache Spark,Pyspark,Databricks,Azure Databricks,我想计算包含子文件夹和子文件的目录(例如-XYZ)大小。 我想要所有文件和XYZ中所有内容的总大小 我可以找到特定路径中的所有文件夹。但我想把所有的尺寸加在一起。 我也明白了 display(dbutils.fs.ls(“/mnt/datalake/../XYZ/../abc.parquet”) 给我abc文件的数据大小。 但是我想要XYZ的完整大小。dbutils.fs.ls没有像cp、mv或rm这样的递归功能。因此,您需要自己迭代。下面是一个片段,它将为您完成这项任务。从Databricks

我想计算包含子文件夹和子文件的目录(例如-XYZ)大小。 我想要所有文件和XYZ中所有内容的总大小

我可以找到特定路径中的所有文件夹。但我想把所有的尺寸加在一起。 我也明白了

display(dbutils.fs.ls(“/mnt/datalake/../XYZ/../abc.parquet”)

给我abc文件的数据大小。
但是我想要XYZ的完整大小。

dbutils.fs.ls没有像
cp
mv
rm
这样的递归功能。因此,您需要自己迭代。下面是一个片段,它将为您完成这项任务。从Databricks笔记本运行代码

from dbutils import FileInfo
from typing import List

root_path = "/mnt/datalake/.../XYZ"

def discover_size(path: str, verbose: bool = True):
  def loop_path(paths: List[FileInfo], accum_size: float):
    if not paths:
      return accum_size
    else:
      head, tail = paths[0], paths[1:]
      if head.size > 0:
        if verbose:
          print(f"{head.path}: {head.size / 1e6} MB")
        accum_size += head.size / 1e6
        return loop_path(tail, accum_size)
      else:
        extended_tail = dbutils.fs.ls(head.path) + tail
        return loop_path(extended_tail, accum_size)

  return loop_path(dbutils.fs.ls(path), 0.0)

discover_size(root_path, verbose=True)  # Total size in megabytes at the end

如果该位置安装在dbfs中。然后您可以使用
du-h
方法(没有测试它)。如果您在笔记本中,请使用以下内容创建新单元格:

%sh
du -h /mnt/datalake/.../XYZ

尝试使用dbutils ls ls命令,获取数据帧中的文件列表,并在大小列上使用聚合函数SUM()进行查询:

val fsds = dbutils.fs.ls("/mnt/datalake/.../XYZ/.../abc.parquet").toDF

fsds.createOrReplaceTempView("filesList")

display(spark.sql("select COUNT(name) as NoOfRows, SUM(size) as sizeInBytes from fileListPROD"))

@Emer的答案很好,但可能会遇到一个
递归错误:最大递归深度很快就超过了
,因为它会对每个文件进行递归(如果有X个文件,则会有X个重叠递归)

以下是仅针对文件夹的递归的相同情况:

%python
from dbutils import FileInfo
from typing import List

def discover_size2(path: str, verbose: bool = True):
  def loop_path(path: str):
    accum_size = 0.0
    path_list = dbutils.fs.ls(path)
    if path_list:
      for path_object in path_list:
        if path_object.size > 0:
          if verbose:
            print(f"{path_object.path}: {path_object.size / 1e6} MB")
          accum_size += path_object.size / 1e6
        else:
          # Folder: recursive discovery
          accum_size += loop_path(path_object.path)
    return accum_size

  return loop_path(path)

du-h不起作用?你能更清楚地回答吗?du-h directorypath你知道为什么这个解决方案不能在更大的目录下工作吗?首先我看到OOM问题并添加了sys.setrecursionlimit(2000)。现在,'RecursionError:maximum recursion depth Oversed in comparison'路径必须非常深,在到达文件之前,您可能有许多“子目录”。试着把2k增加到像500k这样的大数值。我稍后再去拿