为什么在重定向输出时调整控制台缓冲区会引发无效的句柄异常?

时间:2015-01-02 22:57:52

标签: c# windows console stdout handle

在将输出重定向到文件时,调整C#控制台应用程序中的Console.BufferWidth会引发异常。让我们调用示例test1.exe:

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

标准输出很好:

test1.exe
output1
output2

重定向到文件会引发异常:

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很容易忽略,但是我不了解文件句柄或句柄。

为什么句柄无效?

1 个答案:

答案 0 :(得分:6)

重定向到文件

test1.exe > file.txt

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

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

不同的设备具有不同的属性。控制台由其窗口可视化表示,但数据(字符)存储在其缓冲区中。窗口的宽度和高度(请参阅Console.WindowWidthConsole.WindowHeight属性),还有屏幕缓冲区大小 - 宽度和高度(请参阅Console.BufferWidthConsole.BufferHeight属性)。如果打开命令提示符,可以手动编辑这些属性,如果单击标题栏左上角的图标,则会出现下拉菜单中的属性

当您的应用程序执行时

Console.BufferWidth = 240;

它尝试更改当前输出设备(文件)不存在的属性(窗口缓冲区大小)。您的应用程序具有重定向输出,它具有文件句柄,并且该对象不支持Console.BufferWidth。因此,您得到IOException(句柄无效)。

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

  

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