如何使用DataLakeFileSystemClient通过正则表达式查询路径?
使用DataLakeFileSystemClient优化正则表达式路径查询的方法
目前你实现的遍历前缀路径再做正则匹配的方式是可行的,但Azure Data Lake Storage的DataLakeFileSystemClient本身不支持直接在服务端执行正则过滤,不过可以通过以下几个方向优化现有逻辑,减少不必要的开销:
缩小服务端返回的数据集
不要直接全量递归遍历,先把你的正则表达式拆解出可前缀匹配的部分,通过GetPathsAsync的prefix参数提前在服务端过滤。比如你的正则是^raw-data/2024/.*\.parquet$,就可以指定前缀为raw-data/2024/,这样服务端只会返回该前缀下的路径,减少客户端需要处理的数据量。
调整后的代码片段:// 用拆解出的前缀替代原directoryPath,缩小查询范围 await foreach (PathItem pathItem in fileSystemClient.GetPathsAsync(prefix: "raw-data/2024/", recursive: true, cancellationToken: cancellationToken)) { // 后续正则匹配逻辑不变 }预编译正则表达式提升匹配效率
你当前的代码每次循环都会重新解析正则表达式,存在不必要的性能损耗。可以在方法开头预编译Regex对象,复用匹配逻辑:private async static IAsyncEnumerable<string> TraverseDirectories(DataLakeFileSystemClient fileSystemClient, string directoryPath, string filePattern, [EnumeratorCancellation] CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // 预编译正则,根据需求添加选项(比如IgnoreCase忽略大小写) var fileRegex = new Regex(filePattern, RegexOptions.Compiled | RegexOptions.CultureInvariant); await foreach (PathItem pathItem in fileSystemClient.GetPathsAsync(directoryPath, recursive: true, cancellationToken: cancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (pathItem.IsDirectory.HasValue && pathItem.IsDirectory.Value) continue; if (fileRegex.IsMatch(pathItem.Name)) { yield return pathItem.Name; } } }提前跳过目录,减少无效匹配
现有代码里已经做了目录跳过的逻辑,这一步要保留——毕竟正则匹配只针对文件,提前跳过目录能减少不必要的正则调用次数。
如果你的正则模式过于复杂,完全无法拆解出可前缀匹配的部分,那客户端遍历过滤确实是目前唯一的选择,但通过上面的优化可以显著提升整体性能。
内容的提问来源于stack exchange,提问作者codeMonkey
相关产品推荐
相关产品推荐

