2

文档Console.ReadLine说:_

默认情况下,该方法从 256 个字符的输入缓冲区中读取输入。因为这包括 Environment.NewLine 字符,所以该方法可以读取最多包含 254 个字符的行。要读取更长的行,请调用 OpenStandardInput(Int32) 方法。

但是,我可以阅读更多的字符。运行一个简单的程序,例如:

string s = Console.ReadLine();
Console.WriteLine(s);
Console.WriteLine(s.Length);

Console.ReadKey();

输入如下:

aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjj

产生相同的输入,长度为 500。

可运行的例子在这里

那么文档是否已经过时,或者这里的“默认”字样是关键?


更新: Jeremy 发现源代码中定义的限制为 4096 。

我已经验证 .NET Core 应用程序只会从标准输入读取前 4094 个字符(不包括换行符)。

在我的例子中,我实际上有一个 .NET Core 3.1 进程,它启动一个 .NET Framework 4.6 进程,重定向它的 StandardOut 和 StandardIn。我已经验证 .NET Framework 进程可以通过Console.ReadLine().NET Core 3.1 进程通过其中发送 Framework 进程内容成功读取 10 亿个字符fwProcess.StandardInput.WriteLine(Serialize(<some stuff>));

当 .NET Framework 进程被替换为 .NET Core 进程时,这也有效。

因此,在重定向标准输出/标准输入时,似乎 256 个字符的限制不适用,但如果有人能找到解释这一点的最终证明/文档,我将不胜感激。如果还有限制(不包括 OutOfMemory 的情况),但它是 11 亿个字符,我想知道。我还想知道这是否取决于平台(我在 Windows 10 上)。

如果有帮助,这就是我正在运行的代码。

控制台应用程序1:

ProcessStartInfo processInfo = new ProcessStartInfo {
    CreateNoWindow = true,
    FileName = "ConsoleApp2.exe",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardInput = true
};

StringBuilder s = new StringBuilder();
var proc = Process.Start(processInfo);

int n = 1_000_000_000;
for (int i = 0; i < n; i++)
    s.Append("a");

proc.StandardInput.WriteLine(s.ToString());
string s = proc.StandardOutput.ReadLine();
Console.WriteLine(s.Length == n); // logs True

Console.ReadKey();

控制台应用程序2:

string s = Console.ReadLine();
Console.WriteLine(s);
4

1 回答 1

2

这里转述:

默认的 cmd 控制台模式是“ENABLE_LINE_INPUT”,这意味着当代码对标准输入发出 ::ReadFile 调用时, ::ReadFile 不会返回给调用者,直到遇到回车。但是对 ReadFile 的调用只有一个有限大小的缓冲区被传递给它。这意味着 cmd 查看提供给它的缓冲区大小,并根据该行可以有多少字符来确定...如果该行更长,它将无法将所有数据存储到缓冲区中。

打开时使用的默认缓冲区大小Console.In现在是 4096(

该文档是开源的,如果您想提交问题或拉取请求,可以在此处获得。

重定向 StandardOut/StandardIn 时,此限制不适用。从这里

限制是你传递了多少内存。

于 2020-02-07T03:42:40.390 回答