首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我可以用Console.ReadLine阅读超过254个字符,而文档却建议我不能阅读?

为什么我可以用Console.ReadLine阅读超过254个字符,而文档却建议我不能阅读?
EN

Stack Overflow用户
提问于 2020-02-07 00:34:20
回答 1查看 579关注 0票数 2

文档 for Console.ReadLine说:

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

然而,我可以读更多的字符只是很好。运行以下简单程序:

代码语言:javascript
复制
string s = Console.ReadLine();
Console.WriteLine(s);
Console.WriteLine(s.Length);

Console.ReadKey();

输入如下:

代码语言:javascript
复制
aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjj

生成长度为500的相同输入。

可运行的示例这里

那么,文档是过时了,还是这里的“默认”键?

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

我已经证实,.NET核心应用程序只会读取stdin中的前4094个字符(不包括换行符)。

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

当将.NET框架流程替换为.NET核心流程时,这也是有效的。

因此,在重定向stdout/stdin时,似乎不适用256个字符的限制,但如果有人能够找到解释这一点的最终证据/文档,我将不胜感激。如果仍然有一个限制(不包括OutOfMemory的情况),但它是11亿个字符,我想知道。我还想知道这是否与平台有关(我在Windows 10上)。

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

ConsoleApp1:

代码语言:javascript
复制
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();

ConsoleApp2:

代码语言:javascript
复制
string s = Console.ReadLine();
Console.WriteLine(s);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-07 03:42:40

这里转述

默认的cmd控制台模式是"ENABLE_LINE_INPUT",这意味着当代码针对stdin发出::ReadFile调用时,::ReadFile在遇到回车之前不会返回给调用方。但是,对ReadFile的调用只有一个有限大小的缓冲区传递给它。这意味着cmd会查看提供给它的缓冲区大小,并根据该值确定行的长度.如果行更长,则无法将所有数据存储到缓冲区中。

打开Console.In时使用的默认缓冲区大小现在为4096 (来源)。

文档是开源的,如果您想提交问题或请求,可以使用可在这里找到

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

限制是你传入多少内存。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60105591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档