我正在尝试编写一个i18n应用程序。该程序读取一个json文件,该文件包含来自语言的翻译,它基于json结构。
{
"EN": {
"TEXT1": "Hello",
"TEXT2": "March"
},
"DE": {
"TEXT1": "Hallo",
"TEXT2": "März"
}
}
我的程序使用文件类,整个代码
以异步方式读取json文件import 'dart:io';
import 'dart:async';
import 'package:json_object/json_object.dart';
abstract class I18n {
static _I18n _i18n;
factory I18n(String file, String lang) {
if(_i18n == null) {
_i18n = new _I18n(file, lang);
return _i18n;
}
return _i18n;
}
Future<String> getTextByMap(String textId);
}
class _I18n implements I18n {
File _file;
String _lang;
JsonObject _jsonContainer;
JsonObject _jsonFiltered;
Future<JsonObject> _imme;
// Parameters:
// file: The whole path and filename
// lang: Expected language
_I18n(String file, this._lang) {
this._file = new File(file);
}
// Read file and return the content of file.
Future<String> _readFileFromStream() {
var com = new Completer();
this._file.exists()
.then((fileExists) {
if(!fileExists) {
throw new StateError('File not found');
}
return this._file.readAsString()
.then((stream) => com.complete(stream));
});
return com.future;
}
void _convertContentToJson(String stream) {
this._jsonContainer = new JsonObject.fromJsonString(stream);
}
Future<JsonObject> _prepareData() {
return this._readFileFromStream().then((stream) {
_convertContentToJson(stream);
this._jsonFiltered = this._jsonContainer[this._lang];
return this._jsonFiltered;
});
}
Future<String> getTextByMap(String textId) {
return this._prepareData().then((filterd) {
return filterd[textId];
});
}
}
和主要代码
import 'package:i18n/i18n.dart';
void main() {
var i18n = new I18n('../hello.json', 'EN');
i18n.getTextByMap('TEXT1').then((val) => print(val));
i18n.getTextByMap('TEXT2').then((val) => print(val));
}
这里的一切,以dart async方式发生,读取json文件等。每当我调用方法时
i18n.getTextByMap('TEXT1').then((val) => print(val));
它会一次又一次地读取json文件。我试图重写该方法以防止多次读取json文件
Future<String> getTextByMap(String textId) {
if(this._jsonFiltered == null)
{
return this._prepareData().then((filterd) {
return filterd[textId];
});
}
return new Future(() => this._jsonFiltered[textId]);
}
但它也不起作用,因为dart以异步方式工作。
我的问题是,如何将这个json文件内容保存在对象中?只读一次json文件并将内容保存在一个对象中,最好每次都读取json文件,这是我的看法。
它可以以同步方式完成所有事情,然后我就不会有问题,但这不是dart术语。
dart执行I / O操作的顺序是什么顺序?
- 未来
- I / O活动
醇>
答案 0 :(得分:3)
我的解决方案是使用工厂构造函数创建一个类。工厂构造函数始终返回该文件的对象。
你的问题是期货是平行的。因此两个调用都是并行执行的。解决方案是让第一个未来完成,然后做其他事情以获得缓存结果。
然后你可以有一个read()方法读取文件的值,如果它不存在于类&#34;内容&#34;例如属性 - 或者如果该属性不为null,则它在后台加载文件。
在这两种情况下,您都可以收听完成者或未来。
编辑示例代码:
example_async_file_factory.dart
import 'dart:io';
import 'dart:async';
class FileHolder {
String _contents = null;
String path;
static Map<String, FileHolder> _files;
factory FileHolder(String path) {
if (_files == null) {
_files = {};
}
if (_files.containsKey(path)) {
return _files[path];
} else {
final fh = new FileHolder._internal(path);
_files[path] = fh;
return fh;
}
}
FileHolder._internal(this.path);
Future<String> getContents() {
if(_contents != null) {
print("cached");
return new Future.value(_contents);
} else {
print("read");
File f = new File(this.path);
Future<String> future = f.readAsString();
Completer completer = new Completer();
future.then((String c) {
_contents = c;
completer.complete(_contents);
});
return completer.future;
}
}
}
void main() {
FileHolder f = new FileHolder("example_async_file_factory.dart");
f.getContents().then((String contents) {
print(contents.length);
FileHolder f2 = new FileHolder("example_async_file_factory.dart");
f2.getContents().then((String contents) {
print(contents.length);
});
f2.getContents().then((String contents) {
print(contents.length);
});
f.getContents().then((String contents) {
print(contents.length);
});
});
}
输出:
read
1411
cached
cached
cached
1411
1411
1411
此致 罗伯特