在我的程序中,我使用输入流和输出流。这些基本上可以是任何类型的流,但在大多数情况下,它们只是控制台中的标准输入和输出。以下是流的初始化方式:
StreamReader input = null;
StreamWriter output = null;
/* ... */
if (output == null)
{
output = new StreamWriter(Console.OpenStandardOutput());
}
if (input == null)
{
input = new StreamReader(Console.OpenStandardInput());
}
我的问题是来自控制台的输入总是写入控制台。我有一些不想写入控制台的特殊字符。更具体地说,我想使用选项卡自动完成例如。
在谷歌上搜索时,我发现的唯一解决方案是使用Console.ReadKey()。但是,这通常会破坏我对流的支持,因为流没有类似的方法。
我的问题归结为:有没有办法将输入流与输出流分离?解决这个问题的替代方法也是受欢迎的。
控制台类是一个奇怪的野兽。 您将需要 Console.ReadKey() 来执行您想要的操作。 一个问题是,没有它,在用户按下 Enter 键之前,您将无法从流中获得任何输入。 这是一个非常简单的例子:
char inp;
do {
var x = Console.ReadKey(true);
inp = x.KeyChar;
output.Write(inp);
if (x.Key == ConsoleKey.Enter) { Console.WriteLine(); }
} while (inp != 'x');
如果你想坚持使用流范式,你可以做这样的事情:
public class ConsoleStream: StreamReader {
public ConsoleStream(): base(new MemoryStream()) {}
public override int Read() {
var key = Console.ReadKey(true);
return (int) key.KeyChar;
}
}
上面的 MemoryStream 没有被使用,它只是为了允许构建基本的 StreamReader。 您可以像这样使用该类:
var cin = new ConsoleStream();
char inp;
do {
inp = (char) cin.Read();
Console.Write(inp);
if (inp == 'r') { Console.WriteLine(); }
} while (inp != 'x');
如果是我,我只会直接使用ReadKey。