首页 > 解决方案 > 如何将csv数据存储在列表中

问题描述

我想读取一个 csv 文件并将内容存储在 abjects 列表中。所以我创建了相应的对象并创建了一个输入流来读取文件。但是当我尝试从函数外部访问列表时,它是空的,所以我认为数据存储在 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;
  }
}

标签: dart

解决方案


是异步的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,您将获得必须手动处理的完成事件。


推荐阅读