为什么在redirect输出时调整控制台缓冲区会引发无效句柄exception?

在将输出redirect到文件时,调整C#控制台应用程序中的Console.BufferWidth会引发exception。 我们来看一个例子test1.exe:

static void Main(string[] args) { Console.BufferWidth = 240; Console.WriteLine("output1\noutput2"); } 

标准输出很好:

 test1.exe output1 output2 

redirect到文件引发exception:

 test1.exe > file.txt Unhandled Exception: System.IO.IOException: The handle is invalid. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.__Error.WinIOError() at System.Console.SetBufferSize(Int32 width, Int32 height) at System.Console.set_BufferWidth(Int32 value) at test1.Program.Main(String[] args) in \\wopr\falken\test1\Program.cs:line 13 

很容易忽略使用try … catch,但有一些我一般不理解的文件句柄或句柄。

为什么句柄无效?

Solutions Collecting From Web of "为什么在redirect输出时调整控制台缓冲区会引发无效句柄exception?"

重定向到文件

 test1.exe > file.txt 

意味着操作系统会将您的应用程序的输出流从标准输出流(控制台)重定向到文件,这在进程启动时会发生。

控制台和文件都称为“ I / O设备 ”,操作系统为每个设备分配一个称为“ 句柄 ”的唯一ID号。 系统使用此句柄来跟踪设备的属性。

不同的设备有不同的属性。 控制台由其窗口直观地表示,但数据(字符)存储在其缓冲区中。 窗口有其宽度和高度(请参阅Console.WindowWidthConsole.WindowHeight属性),但也有屏幕缓冲区大小 – 宽度和高度(请参阅Console.BufferWidthConsole.BufferHeight属性)。 如果打开“ 命令提示符” ,则可以手动编辑这些属性,然后转到如果单击标题栏左侧图标上显示的下拉菜单中的“ 属性”

当你的应用程序执行

 Console.BufferWidth = 240; 

它试图改变当前输出设备(文件)不存在的属性(窗口缓冲区大小)。 你的应用程序已经重定向了输出,它有一个文件句柄, Console.BufferWidth不支持该对象。 因此你得到这个IOException (句柄是无效的)。

有关Console类的 MSDN页面如何在重定向的情况下设计代码:

当基础流定向到控制台时,正常工作的控制台类成员可能会在例如将流重定向到文件时引发异常。 如果重定向标准流,则编写应用程序以捕获System.IO.IOException异常。 您还可以使用IsOutputRedirected,IsInputRedirected和IsErrorRedirected属性来确定在执行引发System.IO.IOException异常的操作之前是否重定向了标准流。