You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用pikepdf解密Azure Blob存储中非UTF-8编码的PDF流?

问题原因

这个UnicodeDecodeError和PDF编码、pikepdf的编码支持能力没有任何关系,是入参类型使用错误导致的:

  • download_blob().readall() 返回的是PDF的原始二进制字节数据
  • pikepdf.Pdf.open() 接收到bytes类型入参时,会默认将其作为文件路径的字节序列尝试解码为字符串路径,不会直接把bytes当做PDF内容解析,解码过程中遇到非UTF-8的二进制字节就会抛出你看到的报错。
  • pikepdf本身完全支持处理所有标准加密PDF,和PDF内部用什么文本编码、文件存在本地还是Azure Blob存储没有关联,不存在“无法解密非UTF-8编码PDF流”的问题。
修复方法

两种实现方式都可以解决问题,选其一即可:

方法1:用内存字节流直接读取(无需写临时加密文件)

导入io模块,将下载得到的二进制字节包装为BytesIO类文件对象,pikepdf识别到类文件对象入参时会直接读取流内的PDF内容,不会按文件路径解析:

import io
# 原有Blob下载逻辑保留
streamdownloader = blob_client.download_blob().readall()
# 新增包装流的步骤
pdf = pikepdf.Pdf.open(io.BytesIO(streamdownloader), password=password)
# 后续保存、读取逻辑无需改动
pdf.save(dec)

方法2:先落地加密临时文件再读取

如果不想走内存处理,可以先把Blob下载的加密PDF二进制内容写到本地临时文件,再传本地文件路径给pikepdf打开:

streamdownloader = blob_client.download_blob().readall()
temp_encrypted_path = "C:/Users/python-test/source_dir/temp_encrypted.pdf"
# 先写加密文件到本地
with open(temp_encrypted_path, 'wb') as temp_f:
    temp_f.write(streamdownloader)
# 再从本地路径打开加密PDF
pdf = pikepdf.Pdf.open(temp_encrypted_path, password=password)
pdf.save(dec)
其他优化提示
  • 你当前使用的PyPDF2.PdfFileReader是PyPDF2旧版本的废弃API,升级PyPDF2后会直接报属性错误,替换为PyPDF2.PdfReader即可,对应的页数获取从pdfReader.numPages改为len(pdfReader.pages)。
  • 打开本地文件建议使用with上下文管理器,避免手动关闭文件遗漏导致的句柄泄露问题。

内容的提问来源于stack exchange,提问作者Eliot Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 22:06:11