如何在列表中存储CSV数据

时间:2019-06-03 08:29:44

标签: dart

我想读取一个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;
  }
}

1 个答案:

答案 0 :(得分:1)

inputStream是异步的,因此读取文件需要一些时间。 inputStream.transform(...).transform(...).listen(...)调用立即完成,然后当从磁盘中读取某些内容时,流将发出事件,并且listOfStocks将逐渐填充。

如果您“立即”需要列表的内容,即:在执行其他操作之前,您必须阻止,直到列表完全填充。

您可以通过两种方式执行此操作:

  1. 同步读取文件。这会使操作系统阻塞,直到将文件完全读入内存为止。

    var content = file.readAsStringSync(); // Defaults to UTF-8 decoding.
    for (var line in LineSplitter.split(content))
      ...
      lineOfStocks.add(stock);
    }
    print(listOfStocks.length); 
    
  2. 异步读取文件,但等待转换完成:

    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,您可以获得一个完成的事件 手动处理。