为什么在重定向输出时调整控制台缓冲区会引发无效句柄异常?
Why does adjusting console buffer raise invalid handle exception when redirecting output?
在 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 很容易,但是对于文件句柄或一般的句柄,我有一些不了解的地方。
为什么句柄无效?
重定向到文件
test1.exe > file.txt
意味着操作系统正在将您的应用程序的输出流从标准输出流(控制台)重定向到一个文件,这发生在进程启动时。
控制台和文件都称为“I/O 设备”,操作系统为它们各自分配了一个名为“handle”的唯一 ID 号”。系统使用此句柄来跟踪设备的属性。
不同的设备有不同的属性。控制台在视觉上由其 window 表示,但数据(字符)存储在其缓冲区中。 Window 有其宽度和高度(参见 Console.WindowWidth
and Console.WindowHeight
properties) but also screen buffer size - Width and Height (see Console.BufferWidth
and Console.BufferHeight
属性)。如果打开 命令提示符 并转到 drop-down 菜单中的 属性 ,您可以手动编辑这些属性,如果您单击该图标,就会出现该菜单在标题栏的左上角。
当您的应用程序执行时
Console.BufferWidth = 240;
它尝试更改当前输出设备(文件)不存在的属性(window 缓冲区大小)。您的应用程序已重定向输出,它有一个文件句柄,并且 Console.BufferWidth
在 object 上不受支持。因此你得到 IOException
(句柄无效)。
关于 Console
Class 如何在重定向情况下设计代码的 MSDN 页面:
Console class members that work normally when the underlying stream is
directed to a console might throw an exception if the stream is
redirected, for example, to a file. Program your application to catch
System.IO.IOException exceptions if you redirect a standard stream.
You can also use the IsOutputRedirected, IsInputRedirected, and
IsErrorRedirected properties to determine whether a standard stream is
redirected before performing an operation that throws an
System.IO.IOException exception.
在 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 很容易,但是对于文件句柄或一般的句柄,我有一些不了解的地方。
为什么句柄无效?
重定向到文件
test1.exe > file.txt
意味着操作系统正在将您的应用程序的输出流从标准输出流(控制台)重定向到一个文件,这发生在进程启动时。
控制台和文件都称为“I/O 设备”,操作系统为它们各自分配了一个名为“handle”的唯一 ID 号”。系统使用此句柄来跟踪设备的属性。
不同的设备有不同的属性。控制台在视觉上由其 window 表示,但数据(字符)存储在其缓冲区中。 Window 有其宽度和高度(参见 Console.WindowWidth
and Console.WindowHeight
properties) but also screen buffer size - Width and Height (see Console.BufferWidth
and Console.BufferHeight
属性)。如果打开 命令提示符 并转到 drop-down 菜单中的 属性 ,您可以手动编辑这些属性,如果您单击该图标,就会出现该菜单在标题栏的左上角。
当您的应用程序执行时
Console.BufferWidth = 240;
它尝试更改当前输出设备(文件)不存在的属性(window 缓冲区大小)。您的应用程序已重定向输出,它有一个文件句柄,并且 Console.BufferWidth
在 object 上不受支持。因此你得到 IOException
(句柄无效)。
关于 Console
Class 如何在重定向情况下设计代码的 MSDN 页面:
Console class members that work normally when the underlying stream is directed to a console might throw an exception if the stream is redirected, for example, to a file. Program your application to catch System.IO.IOException exceptions if you redirect a standard stream. You can also use the IsOutputRedirected, IsInputRedirected, and IsErrorRedirected properties to determine whether a standard stream is redirected before performing an operation that throws an System.IO.IOException exception.