Flutter冷知識 | 獲取dart的print內容

前言

這得從我在羣裏時不時冒泡提及。java

此刻樓上大佬裝成萌新,因此我就來了。bash

也就是看了羣裏一位老哥寫的 Flutter 組件,能夠查看當前打印的日誌,仍是挺厲害,可是打印的時候就只能調用他給定的方法來 print ,在寫安卓原生的時候有過這一需求,就是須要在 app 內部拿到 System.out.print 方法打印的字符。app

java 中則是開放了這一方法。函數

System.setErr(new PrintStream(***));
System.setOut(new PrintStream(***));
複製代碼

這樣全部的標準輸出與標準錯誤輸出都定向到了本身設置的流中,這個流能夠指向文件、管道、或是文件描述符。測試

大體相關的一些需求:ui

  • 須要主動獲取 dartprint 內容,方便分析,由於過長的內容 print 是會被截斷的。
  • 添加少許代碼的狀況下讓本身的上線產品的輸出不能隨意被看見。

由於在平時的開發中,常常有被調試的手機運行着其餘的 Flutter 程序,本身的電腦終端就能拿到它的輸出。spa

初步分析

從 dart 內部

dartstdio.dart 文件中有如下幾個變量。3d

int _stdinFD = 0;
int _stdoutFD = 1;
int _stderrFD = 2;
複製代碼

還有一個重定向輸出的方法。調試

void _setStdioFDs(int stdin, int stdout, int stderr) {
  _stdinFD = stdin;
  _stdoutFD = stdout;
  _stderrFD = stderr;
}
複製代碼

幾乎這個文件全部的東西都加上了 _ ,而咱們能拿到的只有 stdin/stdout/stderr,而且可以操做的方法也比較少。日誌

從進程

一個進程至少有 0,1,2 三個文件描述符,它們分別對應 stdin/stdout/stderr

舉個例子:

咱們在 c 語言用調用如下代碼:

printf('hi');
複製代碼

它其實等價於:

char tmp = "hi";
write(1, tmp, strlen(tmp));
複製代碼

因此我考慮拷貝這三個文件描述符,讓他們指向其餘的地方。

確保在父進程執行拷貝函數,fork 後的子進程的文件描述符是分開。

dup2 函數

dup2 函數用來拷貝文件描述符。

函數原型:

int dup2 (int oldfd,int newfd)
複製代碼

若參數 newfd 已經被程序使用,則系統就會將 newfd 所指的文件關閉,若 newfd 等於 oldfd ,則返回 newfd ,而不關閉 newfd 所指的文件。dup2 所複製的文件描述符與原來的文件描述符共享各類文件狀態。共享全部的鎖定,讀寫位置和各項權限或 flags 等。

例子

咱們調用

int filefd = open("./tmp.txt", O_RDWR);
dup2(filefd,0);
複製代碼

O_RDWR 表示可讀,可寫。

此時咱們再次調用:

printf('hi');
複製代碼

屏幕上不會再出現任何字符,輸出就直接寫入到了文件 tmp.txt 中。

因此它其實等價於:

char tmp = "hi";
write(filefd, tmp, strlen(tmp));
複製代碼

這也是僞終端實現的主要原理之一。

Flutter 實現

咱們使用 dart:ffi 來完成這個操做。

ffi 相關本文不作具體解釋。

流程就是 dart -> dart:ffi -> c -> dup2

因此咱們只須要簡單的幾行代碼。

int filefd = open("./tmp.txt", O_RDWR);
dup2(filefd, 1);
dup2(filefd, 2);
複製代碼

如此一來,開發者調用 print 函數,亦或者 dart 內部的一些打印,都等價於:

write(filefd, '***', strlen("***"));
複製代碼

全部的內容都會被定向到咱們指定的文件中

測試截圖:

此時個人 vs code 調試終端拿不到任何輸出了,但我能從我設置到的文件中讀取輸出。

平臺差別

在我反覆測試 Linux 桌面版Android 平臺的時候,發如今 LinuxFlutter 桌面 app 上,dartprint 其實就是寫入字符到文件描述符 1,2,但在 Android 設備上,print 寫入到的文件描述符是 3

也就是

dup2(filefd, 3);
複製代碼

over。有問題留言。有錯誤指出。

最後歡迎各位加入Flutter Candies,一塊兒製造可愛好用的🍬 。 (QQ羣:181398081)

相關文章
相關標籤/搜索