.NET CORE 怎么样从控制台中读取输入流

从Console.ReadList/Read 的源码中,可学习到.NET CORE 是怎么样来读取输入流。

也可以学习到是如何使用P/Invoke来调用系统API

Console.ReadList 的源码为

        [MethodImplAttribute(MethodImplOptions.NoInlining)]
        public static string ReadLine()
        {
            return In.ReadLine();
        }

其中In为。


        internal static T EnsureInitialized<T>(ref T field, Func<T> initializer) where T : class =>
            LazyInitializer.EnsureInitialized(ref field, ref InternalSyncObject, initializer);

        public static TextReader In => EnsureInitialized(ref s_in, () => ConsolePal.GetOrCreateReader());

可以看到他是个TextRead

internal static TextReader GetOrCreateReader()
        {
            Stream inputStream = OpenStandardInput();
            return SyncTextReader.GetSynchronizedTextReader(inputStream == Stream.Null ?
                StreamReader.Null :
                new StreamReader(
                    stream: inputStream,
                    encoding: new ConsoleEncoding(Console.InputEncoding),
                    detectEncodingFromByteOrderMarks: false,
                    bufferSize: Console.ReadBufferSize,
                    leaveOpen: true));
        }

继续跳转,查看方法OpenStandardInput


        public static Stream OpenStandardInput()
        {
            return GetStandardFile(Interop.Kernel32.HandleTypes.STD_INPUT_HANDLE, FileAccess.Read);
        }

继续看方法


        private static Stream GetStandardFile(int handleType, FileAccess access)
        {
            IntPtr handle = Interop.Kernel32.GetStdHandle(handleType);
            // 此处源码一坨注释被我删掉了。^_^
            if (handle == IntPtr.Zero || handle == InvalidHandleValue ||
                (access != FileAccess.Read && !ConsoleHandleIsWritable(handle)))
            {
                return Stream.Null;
            }

            return new WindowsConsoleStream(handle, access, GetUseFileAPIs(handleType));
        }

哈哈,终于要看到了Interop.Kernel32.GetStdHandle 这个方法就是调用系统API接口函数的方法。

<!-- Windows -->
  <ItemGroup Condition="'$(TargetsWindows)' == 'true'">
    <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Kernel32\Interop.GetStdHandle.cs">
          <Link>Common\CoreLib\Interop\Windows\Interop.GetStdHandle.cs</Link>
        </Compile>
</ItemGroup>
<!-- Unix -->
<ItemGroup Condition=" '$(TargetsUnix)' == 'true'">
</ItemGroup>

回到GetStandardFile 中看到返回一个WindowsConsoleStream

 
 

useFileAPIs 参数,决定是使用操作系统 ReadFile还是 ReadConsole API。


对于.NET CORE 源码中有很多 XXXX.Unix.cs,XXXX.Windows.cs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值