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

为何Windows的_read()函数无法从STDOUT读取?能否实现该操作?

问题

在Linux系统中我可以用read()从STDOUT读取数据,但Windows系统似乎只允许从STDIN读取、向STDOUT写入。我在Windows上运行了以下代码:

#include <io.h>  // Include for _read()
#include <stdio.h>
#include <string.h>
#include <stdio.h>

int main() {
    char buffer[256];
    int n;
    int fd = 1; // File descriptor for stdout (standard output)

    while ((n = _read(fd, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[n] = '\0'; // Null-terminate the string if needed
        char* p = buffer;
        char* nl;

        while ((nl = strchr(p, '\n')) != NULL) {
            *nl = '\0'; // Null-terminate the line
            printf("Line: %s\n", p); // Process the line
            p = nl + 1; // Move to the next line
        }

        // If there's any remaining data in the buffer, process it
        if (*p != '\0') {
            printf("Remaining: %s\n", p);
        }
    }

    if (n == 0) {
        // End of input (Ctrl+Z on Windows)
        printf("End of input reached. Program exiting.\n");
    }
    else {
        perror("Error reading from stdin");
    }

    return 0;
}

运行后报错:Error reading from fd: Bad file descriptor。想知道:

  1. 为什么Linux与Windows的行为存在差异?
  2. 能否在Windows上用_read()从STDOUT读取数据?

解答

1. Linux与Windows的行为差异原因

核心差异源于两个系统的标准句柄模型设计不同:

  • 在Linux中,遵循「一切皆文件」的设计理念,标准输入(0)、输出(1)、错误(2)本质都是指向内核文件对象的描述符。当程序在终端运行时,stdout和stdin实际上指向同一个终端设备文件(比如/dev/tty),而终端设备是双向可读写的。这时候调用read(1, ...)本质是从终端设备读取数据,和read(0, ...)效果一致;如果stdout被重定向到其他双向对象(比如socket),也能读取数据。
  • 在Windows中,标准句柄是严格单向的:STDIN(文件描述符0)被打开为只读模式,STDOUT(1)和STDERR(2)被打开为只写模式。它们对应的内核对象(比如控制台的输入缓冲区和输出缓冲区)是完全分离的,没有读取权限的句柄调用_read()自然会返回「无效文件描述符」错误。

2. Windows上能否用_read()从STDOUT读取数据?

不能直接这么做。Windows的STDOUT句柄本身不具备读取权限,任何尝试用_read()(或底层Win32 APIReadFile())读取STDOUT的操作都会失败。

如果你的需求是读取控制台输入,直接使用文件描述符0(STDIN)即可;如果是想捕获当前程序自己输出到STDOUT的内容,可以通过管道重定向的方式实现:创建一个匿名管道,将STDOUT重定向到管道的写端,然后从管道的读端读取数据——但这已经不是直接读取原始的STDOUT句柄了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:55:21