我想读取一个csv文件,并将内容存储在对象列表中。因此,我创建了相应的对象,并创建了一个输入流以读取文件。但是,当我尝试从函数外部访问列表时,它是空的,所以我想,数据存储在listOfStocks的副本中,而不是像我想要的那样直接存储在列表中。那么如何将内容存储在列表中?
import 'dart:io';
import 'dart:async';
import 'dart:convert';
main(List arguments) {
final File file = new File("../Data/In.List.toDart.csv");
Stream<List> inputStream = file.openRead();
List<Stock> listOfStocks = new List();
inputStream
.transform(utf8.decoder)
.transform(new LineSplitter())
.listen((String line) {
List row = line.split(',');
Stock stock = new Stock();
stock.setSymbol(row[0]);
stock.setDesc(row[1]);
stock.setExchange(row[2]);
listOfStocks.add(stock);
print(listOfStocks.length);
},
onDone: () { print('All read.'); },
onError: (e) { print(e.toString()); });
print(listOfStocks.length);
}
class Stock {
String symbol;
String desc;
String exchange;
void setSymbol(String symbol) {
this.symbol = symbol;
}
void setDesc(String desc) {
this.desc = desc;
}
void setExchange(String exchange) {
this.exchange = exchange;
}
String getSymbol() {
return symbol;
}
String getDesc() {
return desc;
}
String getExchange() {
return exchange;
}
}
答案 0 :(得分:1)
inputStream
是异步的,因此读取文件需要一些时间。
inputStream.transform(...).transform(...).listen(...)
调用立即完成,然后当从磁盘中读取某些内容时,流将发出事件,并且listOfStocks
将逐渐填充。
如果您“立即”需要列表的内容,即:在执行其他操作之前,您必须阻止,直到列表完全填充。
您可以通过两种方式执行此操作:
同步读取文件。这会使操作系统阻塞,直到将文件完全读入内存为止。
var content = file.readAsStringSync(); // Defaults to UTF-8 decoding.
for (var line in LineSplitter.split(content))
...
lineOfStocks.add(stock);
}
print(listOfStocks.length);
异步读取文件,但等待转换完成:
main(List arguments) async {
...
await inputStream
.transform(utf8.decoder)
.transform(const LineSplitter())
.forEach((String line) { // Use forEach instead of listen
...
listOfStocks.add(stock);
});
print(listOfStocks.length);
}
如果您使用forEach
而不是listen
,它将返回一个完成的将来
当流完成时。使用listen
,您可以获得一个完成的事件
手动处理。