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)

相关文章
相关标签/搜索