Dart readAsStringSync不阅读包含特殊字符(点/句号)的行

aij0ehis  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(79)

我正在我的应用程序中编写一个数据导出/导入功能。输出以文本形式写入csv文件,这似乎工作正常,但数据导入跳过了一些导出行(下面输出csv文件中的“统计”数据),我不明白为什么会发生这种情况。
因此,您可以看到文件是如何构建的,导出例程如下所示:

//
// Default to read files from the documents director
final directory =
    await ExternalPath.getExternalStoragePublicDirectory(
        ExternalPath.DIRECTORY_DOWNLOADS);
//
// Build filename
String filename = 'frequentBackup';
filename = filename + DateTime.now().year.toString();
filename =
    filename + DateTime.now().month.toString().padLeft(2, '0');
filename =
   filename + DateTime.now().day.toString().padLeft(2, '0');
filename = '$filename.csv';
String fullname = '$directory/$filename'; // Add path
//
// Build output and save to disk
try {
  //
  // Export Instruments
  File(fullname).writeAsStringSync(exportInstruments(),
      mode: FileMode.write, flush: true);
  //
  // Export Range Names
  File(fullname).writeAsStringSync(exportRanges(),
      mode: FileMode.append, flush: true);
  //
  // Export Frequencies
  File(fullname).writeAsStringSync(exportFrequencies(),
      mode: FileMode.append, flush: true);
  //
  // Export FrequencySort
  File(fullname).writeAsStringSync(
      await exportFrequencySort(database: widget._db),
      mode: FileMode.append,
      flush: true);
  //
  // Export Statistics
  File(fullname).writeAsStringSync(
      await exportStatistics(database: widget._db),
      mode: FileMode.append,
      flush: true);
  //
  // Export AppSettings
  await File(fullname).writeAsString(exportAppSettings(),
      mode: FileMode.append, flush: true);
  //
  // Notify user that the export is complete
  String message = 'Export to $filename complete.';
  showSnackBar(message: message);

用于创建导出行的各个函数如下所示:
仪器数据:

String exportInstruments() {
  String output = '';
  Map<int, String> instruments = Instruments.data();

  instruments.forEach((id, name) {
    output += 'instrument,';
    output += 'id:$id,';
    output += 'name:$name\n';
  });
  return output;
}

范围数据:

String exportRanges() {
  String output = '';
  Map<int, String> ranges = Ranges.data();

  ranges.forEach((id, name) {
    output += 'range name,';
    output += 'id:$id,';
    output += 'name:$name\n';
  });
  return output;
}

频率数据:

String exportFrequencies() {
  String output = '';
  List<Record> frequencies = Frequencies.master();

  for (Record r in frequencies) {
    output += 'frequency,';
    output += 'fid:${r.id},';
    output += 'iid:${r.instrumentID},';
    output += 'iname:${r.instrument},';
    output += 'rid:${r.rangeNameID},';
    output += 'rname:${r.rangeName},';
    output += 'rtype:${r.rangeType},';
    output += 'fstart:${r.freqStart},';
    output += 'fend:${r.freqEnd},';
    output += 'fundamental:${r.fundamental},';
    output += 'audiofile:${r.audioFile},';
    output += 'audiopath:${r.audioPath} \n';
  }
  return output;
}

频率排序数据:

Future<String> exportFrequencySort({required MyDatabase database}) async {
  String output = '';

  // Get statistics records from the database (Future)
  await DataFrequencies.getSortOrder(db: database).then((order) {
    order.forEach((position, fid) {
      output += 'frequencyorder,';
      output += 'position:$position,';
      output += 'fid:$fid\n';
    });
  });

  return output;
}

统计数据:

Future<String> exportStatistics({required MyDatabase database}) async {
  String output = '';

  // Get statistics records from the database (Future)
  await DataStatistics.getAllStatistics(db: database).then((statistics) {
    for (StatRecord s in statistics) {
      output += 'statistic,';
      output += 'type:${s.type.toString()},';
      output += 'fid:${s.id},';
      output += 'iid:${s.iid},';
      output += 'rid:${s.rid},';
      output += 'presented:${s.presented},';
      output += 'correct:${s.correct}\n';
    }
  });
  return output;
}

应用程序设置数据:

String exportAppSettings() {
  String output = '';
  Map<String, dynamic> settings = Settings.getAllSettings();

  settings.forEach((name, setting) {
    output += 'setting,';
    output += 'name:$name,';
    output += 'setting:$setting\n';
  });
  return output;
}

这些函数生成的输出csv文件如下所示:

instrument,id:1,name:banjo 
instrument,id:2,name:piano
instrument,id:3,name:xylophone 
range name,id:1,name:crump
range name,id:2,name:kapow
range name,id:3,name:whump
frequency,fid:1,iid:1,iname:banjo ,rid:1,rname:crump,rtype:R,fstart:30,fend:60,fundamental:1,audiofile:,audiopath: 
frequency,fid:2,iid:1,iname:banjo ,rid:2,rname:kapow,rtype:R,fstart:100,fend:250,fundamental:0,audiofile:,audiopath: 
frequency,fid:3,iid:1,iname:banjo ,rid:3,rname:whump,rtype:R,fstart:1000,fend:2000,fundamental:0,audiofile:,audiopath: 
frequency,fid:4,iid:2,iname:piano,rid:1,rname:crump,rtype:R,fstart:1000,fend:1500,fundamental:0,audiofile:,audiopath: 
frequency,fid:5,iid:2,iname:piano,rid:2,rname:kapow,rtype:R,fstart:2000,fend:3000,fundamental:1,audiofile:,audiopath: 
frequency,fid:6,iid:2,iname:piano,rid:3,rname:whump,rtype:R,fstart:4000,fend:5000,fundamental:0,audiofile:,audiopath: 
frequencyorder,position:0,fid:1
frequencyorder,position:1,fid:2
frequencyorder,position:2,fid:3
frequencyorder,position:3,fid:4
frequencyorder,position:4,fid:5
frequencyorder,position:5,fid:6
statistic,type:FlashType.frequency,fid:1,iid:1,rid:1,presented:0,correct:0
statistic,type:FlashType.frequency,fid:2,iid:1,rid:2,presented:0,correct:0
statistic,type:FlashType.frequency,fid:3,iid:1,rid:3,presented:0,correct:0
statistic,type:FlashType.frequency,fid:4,iid:2,rid:1,presented:0,correct:0
statistic,type:FlashType.frequency,fid:5,iid:2,rid:2,presented:0,correct:0
statistic,type:FlashType.frequency,fid:6,iid:2,rid:3,presented:0,correct:0
statistic,type:FlashType.ranges,fid:1,iid:1,rid:1,presented:0,correct:0
statistic,type:FlashType.ranges,fid:2,iid:1,rid:2,presented:0,correct:0
statistic,type:FlashType.ranges,fid:3,iid:1,rid:3,presented:0,correct:0
statistic,type:FlashType.ranges,fid:4,iid:2,rid:1,presented:0,correct:0
statistic,type:FlashType.ranges,fid:5,iid:2,rid:2,presented:0,correct:0
statistic,type:FlashType.ranges,fid:6,iid:2,rid:3,presented:0,correct:0
statistic,type:FlashType.fundamentals,fid:1,iid:1,rid:1,presented:0,correct:0
statistic,type:FlashType.fundamentals,fid:2,iid:1,rid:2,presented:0,correct:0
statistic,type:FlashType.fundamentals,fid:3,iid:1,rid:3,presented:0,correct:0
statistic,type:FlashType.fundamentals,fid:4,iid:2,rid:1,presented:0,correct:0
statistic,type:FlashType.fundamentals,fid:5,iid:2,rid:2,presented:0,correct:0
statistic,type:FlashType.fundamentals,fid:6,iid:2,rid:3,presented:0,correct:0
statistic,type:FlashType.sounds,fid:1,iid:1,rid:1,presented:0,correct:0
statistic,type:FlashType.sounds,fid:2,iid:1,rid:2,presented:0,correct:0
statistic,type:FlashType.sounds,fid:3,iid:1,rid:3,presented:0,correct:0
statistic,type:FlashType.sounds,fid:4,iid:2,rid:1,presented:0,correct:0
statistic,type:FlashType.sounds,fid:5,iid:2,rid:2,presented:0,correct:0
statistic,type:FlashType.sounds,fid:6,iid:2,rid:3,presented:0,correct:0
setting,name:colourOneEnabled,setting:false
setting,name:colourOne,setting:#fffff59d
setting,name:colourTwoEnabled,setting:false
setting,name:colourTwo,setting:#ff9dffb1
setting,name:fontColourEnabled,setting:false
setting,name:fontColour,setting:#ff000000
setting,name:fundamentalColourEnabled,setting:false
setting,name:fundamentalColour,setting:#ff4caf50
setting,name:disabledColourEnabled,setting:false
setting,name:disabledColour,setting:#ff9e9e9e
setting,name:themeMode,setting:ThemeMode.dark
setting,name:leftHanded,setting:false

读取此文件的导入例程使用readAsStringSync(如果我使用readAsLinesSync,也会遇到相同的问题),如下所示:

String fullName = result.files.first.path as String;
dynamic temp = File(fullName).readAsStringSync();
print('$temp');

调试控制台输出如下所示:

I/flutter ( 6499): instrument,id:1,name:banjo 
I/flutter ( 6499): instrument,id:2,name:piano 
I/flutter ( 6499): instrument,id:3,name:xylophone 
I/flutter ( 6499): range name,id:1,name:crump 
I/flutter ( 6499): range name,id:2,name:kapow 
I/flutter ( 6499): range name,id:3,name:whump 
I/flutter ( 6499): frequency,fid:1,iid:1,iname:banjo ,rid:1,rname:crump,rtype:R,fstart:30,fend:60,fundamental:1,audiofile:,audiopath: 
I/flutter ( 6499): frequency,fid:2,iid:1,iname:banjo ,rid:2,rname:kapow,rtype:R,fstart:100,fend:250,fundamental:0,audiofile:,audiopath: 
I/flutter ( 6499): frequency,fid:3,iid:1,iname:banjo ,rid:3,rname:whump,rtype:R,fstart:1000,fend:2000,fundamental:0,audiofile:,audiopath: 
I/flutter ( 6499): frequency,fid:4,iid:2,iname:piano,rid:1,rname:crump,rtype:R,fstart:1000,fend:1500,fundamental:0,audiofile:,audiopath: 
I/flutter ( 6499): frequency,fid:5,iid:2,iname:piano,rid:2,rname:kapow,rtype:R,fstart:2000,fend:3000,fundamental:1,audiofile:,audiopath: 
I/flutter ( 6499): frequency,fid:6,iid:2,iname:piano,rid:3,rname:whump,rtype:R,fstart:4000,fend:5000,fundamental:0,audiofile:,audiopath: 
I/flutter ( 6499): frequencyorder,position:0,fid:1 
I/flutter ( 6499): frequencyorder,position:1,fid:2 
I/flutter ( 6499): frequencyorder,position:2,fid:3 
I/flutter ( 6499): frequencyorder,position:3,fid:4 
I/flutter ( 6499): frequencyorder,position:4,fid:5 
I/flutter ( 6499): frequencyorder,position:5,fid:6 
I/flutter ( 6499): setting,name:colourOneEnabled,setting:false 
I/flutter ( 6499): setting,name:colourOne,setting:#fffff59d 
I/flutter ( 6499): setting,name:colourTwoEnabled,setting:false 
I/flutter ( 6499): setting,name:colourTwo,setting:#ff9dffb1 
I/flutter ( 6499): setting,name:fontColourEnabled,setting:false 
I/flutter ( 6499): setting,name:fontColour,setting:#ff000000 
I/flutter ( 6499): setting,name:fundamentalColourEnabled,setting:false 
I/flutter ( 6499): setting,name:fundamentalColour,setting:#ff4caf50 
I/flutter ( 6499): setting,name:disabledColourEnabled,setting:false 
I/flutter ( 6499): setting,name:disabledColour,setting:#ff9e9e9e 
I/flutter ( 6499): setting,name:themeMode,setting:ThemeMode.system 
I/flutter ( 6499): setting,name:leftHanded,setting:false

请注意,“frequencyorder”和“setting”行之间缺少“statistic”行。
我正在运行Flutter(Channel stable,3.7.11,在Microsoft Windows [版本10.0.22621.1555]上,区域设置en-GB)。
有人知道为什么会这样吗?

xxhby3vn

xxhby3vn1#

根据这里的帖子:Special characters in Flutter,解决方案是将点转换为unicode,然后导出String。当readAsString或readAsLines读取时,unicode会自动转换回点。我的导出代码现在看起来像这样:

Future<String> exportStatistics({required MyDatabase database}) async {
      String output = '';

      // Get statistics records from the database (Future)
      await DataStatistics.getAllStatistics(db: database).then((statistics) {
        for (StatRecord s in statistics) {
          output += 'statistic,';
          dynamic temp = s.type.toString().replaceAll('.', '\u002e');
          output += 'type:$temp,';
          output += 'fid:${s.id},';
          output += 'iid:${s.iid},';
          output += 'rid:${s.rid},';
          output += 'presented:${s.presented},';
          output += 'correct:${s.correct}\n';
        }
      });
      return output;
    }

这在测试中并不明显,因为我还了解到,至少在我的设置中,当我在物理连接的设备上测试应用时,我需要在导入新文件之前清除应用上该高速缓存。如果我不这样做,那么即使在更改导出例程之后,应用似乎也在导入以前缓存的文件版本。重新启动应用程序并将数据重新导出到导出文件。因此,更改看起来像是没有工作。

相关问题