首頁  >  文章  >  電腦教學  >  .NET9 Linux-x64下Console.WriteLine原理

.NET9 Linux-x64下Console.WriteLine原理

WBOY
WBOY轉載
2024-02-23 09:04:10601瀏覽

.NET9 Linux-x64下Console.WriteLine原理

1.前言

#之前聊過Windows下面Console.WriteLine的運行過程常用Console.WriteLine原理,你知道嗎?本篇看下它在Linu-x64下面最新.NET9運行過程

2.託管程式碼

#

在.NET中,通常使用StreamReader和StreamWriter這兩個類別來進行流讀寫入操作,它們的命名空間位於System.IO中。這些類別包含在託管庫System.Runtime.dll中。下面是一個簡單的範例操作:

using (StreamWriter writer = File.CreateText("newfile.txt"))
{
await writer.WriteLineAsync("First line of example");
await writer.WriteLineAsync("and second line");
}

StreamWriter和StreamReader分別衍生自TextWriter和TextReader。 Console.WriteLine列印出的字串,則是在CLR庫裡面直接透過TextWriter寫入到的資料流/裝置。

例如範例:

static void Main(string[] args)
{
 Console.WriteLine("Call Main");
}

Console.WriteLine會呼叫Out.EnsureInitialized函數,Out即為TextWriter型,程式碼如下:

源码地址:https://github.com/dotnet/runtime/blob/main/src/libraries/System.Console/src/System/Console.cs

public static TextWriter Out
{
get
{
static TextWriter EnsureInitialized()
{
lock (s_syncObject)
{
if (s_out == null)
{
Volatile.Write(ref s_out, CreateOutputWriter(ConsolePal.OpenStandardOutput()));
}
return s_out;
}
}
}
}

EnsureInitialized函數裡面呼叫了Volatile.Write函數,Volatile.Write函數的意思是,把參數二的值寫入到參數一字段裡面去。這裡的解釋就是把CreateOutputWriter(ConsolePal.OpenStandardOutput())回傳的值寫入s_out字段,s_out也是TextWriter型別。

這裡看下CreateOutputWriter(ConsolePal.OpenStandardOutput())回傳的值是啥。 CreateOutputWriter函數如下:

源码地址:https://github.com/dotnet/runtime/blob/main/src/libraries/System.Console/src/System/Console.cs


private static TextWriter CreateOutputWriter(Stream outputStream)
{
return outputStream == Stream.Null ?
TextWriter.Null :
TextWriter.Synchronized(new StreamWriter(
stream: outputStream,
encoding: OutputEncoding.RemovePreamble(), 
bufferSize: WriteBufferSize,
leaveOpen: true)
{
AutoFlush = true
});
}

可以看到CreateOutputWriter回傳的依舊是TextWriter,也就是說Volatile.Write把流數據寫入到流數據,然後從設備上列印出來。

這裡寫入的流資料值到底是什麼呢?繼續看ConsolePal.OpenStandardOutput()函數,它回傳的是Stream類型。

源码地址:
https://github.com/dotnet/runtime/blob/main/src/libraries/System.Console/src/System/ConsolePal.Unix.cs


public static Stream OpenStandardOutput()
{
return new UnixConsoleStream(Interop.CheckIo(Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDOUT_FILENO)), FileAccess.Write);
}

這裡是Linux/Unix下面的操作,OpenStandardOutput裡面實例化了一個UnixConsoleStream類,UnixConsoleStream的建構子裡面,第一個參數是Interop.CheckIo(Interop.Sys.Dup(Interop.Sys.FileDescriptors.STDOUT_FILENO) )。 Interop.Sys.Dup是Linux下面進行文件表項操作的函數。 CheckIo則是個檢查函數,此處可以忽略。

舉個例子,一般的來說Linux下面在終端機上印出一個hello World通常透過printf(“hello Word”)

printf -> stdout(标准输出) -> Dup(STDOUT_FILENO) ->终端输出

可見Linux下面是透過Dup函數傳遞參數STDOUT_FILENO進行終端操作的,UnixConsoleStream第二個參數是FileAccess.Write,表示寫入字串。然後把這個Stream封裝後返回,透過Volatile.Write寫入到終端流裡面列印出來。

那麼其實很清晰了,流程大致如下:

Console.WriteLine ->Out.EnsureInitialized -> ConsolePal.OpenStandardOutput() -> I

以上是.NET9 Linux-x64下Console.WriteLine原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:mryunwei.com。如有侵權,請聯絡admin@php.cn刪除