如何通过URL读取BUFR文件?解决BytesIO与eccodes调用报错
直接从URL加载读取BUFR文件的解决方案
问题根源
你遇到的两个错误本质原因:
- TypeError: expected str, bytes or os.PathLike object, not BytesIO:
open()函数仅接受文件路径类参数(字符串/路径对象),不能直接传入BytesIO对象——BytesIO本身就是类文件对象,无需用open()包裹。 - io.UnsupportedOperation: fileno:多数传统BUFR解析库(如基于C的ecCodes绑定)依赖真实文件的系统文件描述符(fileno),而BytesIO是纯内存对象,不提供该属性,因此触发报错。
可行解决方案
方案1:使用支持内存类文件对象的BUFR库
推荐使用pybufr-ecmwf,该库原生支持从BytesIO读取数据,无需依赖真实文件。
- 安装依赖:
pip install pybufr-ecmwf
- 示例代码:
import requests from io import BytesIO from pybufr_ecmwf import BUFR # 替换为目标BUFR文件的URL bufr_url = "https://example.com/path/to/target.bufr" response = requests.get(bufr_url) # 直接将BytesIO对象传入库进行解析 bufr = BUFR(BytesIO(response.content)) bufr.read() # 示例:读取第一个数据子集 first_subset = bufr.get_subset(0) print(first_subset)
方案2:使用内存临时文件兼容依赖fileno的库
如果必须使用依赖文件描述符的库(如ecCodes的Python绑定),可以用tempfile.SpooledTemporaryFile——它默认将数据存储在内存中,仅当数据量超过阈值时才写入磁盘,完全满足“无需下载到本地磁盘”的要求。
示例代码:
import requests import tempfile from eccodes import codes_bufr_new_from_file, codes_get, codes_bufr_delete bufr_url = "https://example.com/path/to/target.bufr" response = requests.get(bufr_url) # 创建内存临时文件,读写二进制模式 with tempfile.SpooledTemporaryFile(mode='wb+') as tmp_file: tmp_file.write(response.content) tmp_file.seek(0) # 将文件指针重置到开头 # 用ecCodes加载BUFR文件 bufr_handle = codes_bufr_new_from_file(tmp_file) # 示例:读取BUFR版本号 edition = codes_get(bufr_handle, "edition") print(f"BUFR版本:{edition}") # 释放资源 codes_bufr_delete(bufr_handle)
内容的提问来源于stack exchange,提问作者Woodz
相关产品推荐
相关产品推荐

