我正在我的应用程序中编写一个数据导出/导入功能。输出以文本形式写入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)。
有人知道为什么会这样吗?
1条答案
按热度按时间xxhby3vn1#
根据这里的帖子:Special characters in Flutter,解决方案是将点转换为unicode,然后导出String。当readAsString或readAsLines读取时,unicode会自动转换回点。我的导出代码现在看起来像这样:
这在测试中并不明显,因为我还了解到,至少在我的设置中,当我在物理连接的设备上测试应用时,我需要在导入新文件之前清除应用上该高速缓存。如果我不这样做,那么即使在更改导出例程之后,应用似乎也在导入以前缓存的文件版本。重新启动应用程序并将数据重新导出到导出文件。因此,更改看起来像是没有工作。