为什么在Python2.x中使用msvcrt时会出现IOError?

为什么在Python2.x中使用msvcrt时会出现IOError?,python,windows,python-2.7,Python,Windows,Python 2.7,我正在尝试在Windows中使用python2.x中的HTML-PDF Web服务生成PDF。这个链接说,如果我将二进制文件写入标准输出,我需要修改它 def generate_pdf(): pdf = callservice(html) if pdf is not None and sys.platform == "win32": import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O

我正在尝试在Windows中使用
python2.x
中的HTML-PDF Web服务生成PDF。这个链接说,如果我将二进制文件写入标准输出,我需要修改它

def generate_pdf():
    pdf = callservice(html)
    if pdf is not None and sys.platform == "win32":
        import os, msvcrt
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    return pdf

def process():
    pdf = generate_pdf()
    # This comes as IOError Errno 12 not enough space
E:\
此程序运行的驱动器有10GB可用空间。有人知道会发生什么吗<代码>C:\驱动器也有10 GB的可用空间。我们是否应该检查
msvcrt
的源代码以了解发生了什么。我正在尝试检查。

这从原则上解释了正在发生的事情,回溯将显示一个确切的失败呼叫

特别是,当没有足够的数据可读取时,尝试
sys.stdin.read()
大于32767字节的数据块将导致
IOError
“[Errno 12]空间不足”。考虑在Windows 7上运行以下示例:

python -c "import sys; data = sys.stdin.read(32768)"

您正在将PDF文件写入到stdout,它已重定向到驱动器
E:
或驱动器
C:
?sys.stdout.fileno()仅为1,我以python file.py的形式从Shell运行此脚本,这是否回答了您的问题?如果您没有将stdout重定向到磁盘文件,我看不出有任何理由将其更改为二进制模式。您的脚本试图在哪里创建文件?在工作目录中?工作目录取决于python.exe的启动方式。它与“file.py”的位置无关。Windows C运行时实现了low(POSIX)和标准I/O。Python 2.x
file
objects包装C标准I/O
file
streams,包装POSIX整数文件描述符(反过来映射到实际的Windows
file
句柄)。
fileno
方法返回文件描述符。最初,C运行时的3个标准
文件
流--
stdin
stdout
stderr
--作为文件描述符0、1和2打开,最初是Python的
sys.stdin
sys.stdout
,它们是,和
sys.stderr
包装相应的C
文件
流。这是人们解释错误消息时的问题。OP说这是一个
IOError
“没有磁盘空间”。但是Windows CRT没有这样的信息。有
ENOMEM
(12,“空间不足”)和
ENOSPC
(28,“设备上没有剩余空间”)。您正在举一个
ENOMEM
的例子。显然,您使用的是Windows7或更早版本,它使用旧的ALPC控制台子系统。这将在conhost.exe和客户机进程python.exe之间设置一个64K共享堆。试图分配一个大于共享堆中最大可用块的读取缓冲区时,会出现与内存相关的错误。Windows 8+有一个完全不同的控制台子系统,它使用驱动程序而不是ALPC,并且没有这个问题。感谢您的更正,您在所有细节上都是正确的。我的例子与这个问题不太相关。你太仓促了,认为这个例子不相关。Nishant的代码出现了
ENOMEM
错误——可能是在控制台上以二进制模式写入
stdout
时出现的。在Windows 8之前,这仅限于与conhost.exe共享的64K堆中最大的可用块。到目前为止,在评论中,我还没有看到将
stdout
设置为二进制模式的理由——如果
stdout
被重定向到磁盘文件或管道,而不是控制台,那就好了。@Nishant,你真的在将pdf写入
stdout
?如果是,请重定向到文件,例如
python script.py>output.pdf
。shell将打开
output.pdf
,并将句柄作为其
standardpoutput
句柄传递给python.exe。在启动时,Python中的C运行时将以文本模式将其映射到低I/O文件描述符1,该描述符由C
stdout
流包装,该流由Python
sys.stdout
包装。然后,您的脚本必须将文件描述符1(即
sys.stdout.fileno()
)更改为二进制模式,就像您已经做的那样,写入“output.pdf”,而无需C运行时将
“\n”
转换为
”\r\n”