是否有一种简单的方法可以打开文件并不断读取它而不会在EOF上关闭流?像Unix命令tail -f
。
只需在API文档中描述EOF
之前阅读。但我看不到一种明显/简单的方法来阻止或暂停流以获得更多输入。
一种解决方案是重复重新打开文件,并在检测到文件大小发生变化时继续读取上一个已知长度。
答案 0 :(得分:1)
像这样的东西
import 'dart:io';
void main(List<String> args ) {
var file = new File("test.txt");
print(file.absolute);
var openFuture = file.open(mode: FileMode.READ);
openFuture.then((raf) => raf.length().then((len) => raf.setPosition(len)
.then((raf) => raf.readXxx...
}
您还可以使用Directory.watch
获取有关更改的通知,然后重新打开并从上一个已知位置读取。
答案 1 :(得分:1)
(尽管这个问题现在已经有很多年了,但我今天偶然发现了同样的问题,找不到可行的解决方案,因此不得不推出自己的解决方案,并希望与未来几代 Dart 程序员分享我的发现.;-))
dart:io
包与一些流和 async-await 魔法相结合,应该提供实现类似“tail -f”的功能所需的一切:
import 'dart:typed_data';
import 'dart:io';
Stream<List<int>> tail(final File file) async* {
final randomAccess = await file.open(mode: FileMode.read);
var pos = await randomAccess.position();
var len = await randomAccess.length();
// Increase/decrease buffer size as needed.
var buf = Uint8List(8192);
Stream<Uint8List> _read() async* {
while (pos < len) {
final bytesRead = await randomAccess.readInto(buf);
pos += bytesRead;
yield buf.sublist(0, bytesRead);
}
}
// Step 1: read whole file
yield* _read();
// Step 2: wait for modify events and read more bytes from file
await for (final event in file.watch(events: FileSystemEvent.modify)) {
if ((event as FileSystemModifyEvent).contentChanged) {
len = await (randomAccess.length());
yield* _read();
}
}
}
这个函数 (tail
) 可以这样使用:
import 'dart:convert';
import 'dart:io';
void main() {
final file = File('/var/log/messages');
tail(file).transform(utf8.decoder).transform(LineSplitter()).forEach((line) {
// Do something with the line that has been read, e.g. print it out...
print(line);
});
}