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

使用zstandard文件作为子进程输入输出时遇fileno属性缺失错误求方案

解决zstandard流与subprocess管道兼容问题

错误原因很明确:subprocess的stdin/stdout参数要求传入的对象必须具备fileno()方法(比如本地文件、系统管道、subprocess.PIPE),但zstandard.open()返回的是Python层面的压缩/解压流对象,没有这个系统级文件描述符属性,因此触发AttributeError。

下面提供两种实用解决方案:


方案1:用系统zstd命令构建管道(推荐)

直接借助系统自带的zstd命令处理压缩/解压,和目标进程串成管道链,完全利用操作系统的流式管道能力,内存占用极低,处理大文件效率最高,也符合Unix风格的管道用法。

import subprocess
import zstandard

# 生成测试用的压缩文件(仅示例,实际可直接用系统zstd命令生成)
with zstandard.open('a.txt.zst', 'w') as f:
    f.write('hello\n')

# 构建完整管道链:zstd解压 -> 目标进程(cat) -> zstd压缩
with open('a.txt.zst', 'rb') as input_file, open('b.txt.zst', 'wb') as output_file:
    # 第一步:解压输入文件到标准输出
    decompress_proc = subprocess.Popen(
        ['zstd', '-d', '-c'],  # -c表示输出到stdout
        stdin=input_file,
        stdout=subprocess.PIPE
    )
    # 第二步:运行目标处理进程(这里用cat示例,实际替换为你的链式程序)
    target_proc = subprocess.Popen(
        ['cat'],
        stdin=decompress_proc.stdout,
        stdout=subprocess.PIPE
    )
    # 第三步:将处理结果压缩后写入输出文件
    compress_proc = subprocess.Popen(
        ['zstd', '-c'],
        stdin=target_proc.stdout,
        stdout=output_file
    )

    # 等待所有进程执行完成
    decompress_proc.wait()
    target_proc.wait()
    compress_proc.wait()

方案2:用Python线程中转流数据

如果必须依赖Python的zstandard库(比如需要自定义压缩参数、系统无zstd命令),可以通过线程中转Python流和子进程管道的数据,只要做好流的关闭和异常处理,完全可靠。

import subprocess
import zstandard
import threading

def zstd_to_pipe(zstd_stream, pipe):
    """将zstandard流的数据写入子进程输入管道"""
    try:
        # 按1MB块读取,避免内存过载
        while chunk := zstd_stream.read(1024 * 1024):
            pipe.write(chunk)
    finally:
        pipe.close()  # 关闭管道,告知子进程输入结束

def pipe_to_zstd(pipe, zstd_stream):
    """从子进程输出管道读取数据,写入zstandard流"""
    try:
        while chunk := pipe.read(1024 * 1024):
            zstd_stream.write(chunk)
    finally:
        zstd_stream.close()  # 确保压缩流写入完成并关闭

# 生成测试压缩文件
with zstandard.open('a.txt.zst', 'w') as f:
    f.write('hello\n')

# 打开压缩输入和输出流
f_in = zstandard.open('a.txt.zst', 'rb')
f_out = zstandard.open('b.txt.zst', 'wb')

# 启动子进程,用PIPE连接输入输出
target_proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

# 启动两个线程分别处理输入和输出中转
thread_in = threading.Thread(target=zstd_to_pipe, args=(f_in, target_proc.stdin))
thread_out = threading.Thread(target=pipe_to_zstd, args=(target_proc.stdout, f_out))

thread_in.start()
thread_out.start()

# 等待子进程和线程完成
target_proc.wait()
thread_in.join()
thread_out.join()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:04:58