如何将Microsoft Graph获取的邮件附件ContentBytes写入本地文件
解决方案
核心错误原因
- 微软Graph API返回的
ContentBytes字段是Base64编码的字符串,并非原生二进制字节数组,直接写入会导致文件损坏 - 提前调用
[System.IO.File]::Create()后未释放文件句柄,导致后续写入操作被锁定,生成空文件 - 手动创建FileStream写入后未关闭刷新缓冲区,数据未落地到磁盘
正确实现代码
$theFolderToUse = "C:\temp" # 提前创建目标目录避免路径不存在报错 if (-not (Test-Path -Path $theFolderToUse)) { New-Item -ItemType Directory -Path $theFolderToUse | Out-Null } foreach ($att in $emailAttachmentResult.value) { # 过滤仅处理文件类型附件,跳过内嵌的邮件、日历项等非文件附件 if ($att.'@odata.type' -eq '#microsoft.graph.fileAttachment') { $outputPath = Join-Path -Path $theFolderToUse -ChildPath $att.Name # 把Base64字符串转换为原生二进制字节数组 $rawBytes = [System.Convert]::FromBase64String($att.ContentBytes) # 直接写入文件,方法内部自动处理文件创建、写入、句柄释放 [System.IO.File]::WriteAllBytes($outputPath, $rawBytes) } }
原有写法的问题说明
- 第一种空文件问题:
[System.IO.File]::Create()会返回处于打开状态的文件流对象,未手动释放的情况下文件被锁定,WriteAllBytes无法写入数据。WriteAllBytes本身支持自动创建不存在的文件,无需提前调用Create方法。 - 第二种FileStream空文件问题:首先没有做Base64转码,其次写入完成后没有调用
Close()/Dispose()释放流,缓冲区数据没有刷入磁盘。 - 第三种文件损坏问题:将Base64字符串直接按Unicode编码转字节数组,存储的是Base64文本内容的编码结果,并非原附件的二进制内容,所以文件无法正常打开。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

