У меня есть следующий код:
class FileData {
Future<String> get _localPath async {
print('D: Local'); //D
final directory = await getApplicationDocumentsDirectory();
print('D: Directory: $directory'); //D
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
print('D: Path: $path'); //D
return File('$path/file.dat');
}
Future<File> _future;
Future<RandomAccessFile> _futureRandomAccessFile;
File _file;
RandomAccessFile _randomAccessFile;
FileData() {
print('D: First'); //D
_future = _localFile;
_future = _future.then(
(File file) {
print('D: Stuff'); //D
if(file == null) throw 'file == null';
_file = file;
print('D: Foo'); //D
_futureRandomAccessFile = file.open(mode: FileMode.append);
_futureRandomAccessFile = _futureRandomAccessFile.then(
(RandomAccessFile randomAccessFile) {
if(randomAccessFile == null) throw 'randomAccessFile == null';
_randomAccessFile = randomAccessFile;
print('D: Position: ${_randomAccessFile.positionSync()}'); //D
int byte = DateTime.now().second; //D
print('D: Write: $byte'); //D
_randomAccessFile.writeByte(byte); //D
return randomAccessFile;
},
onError: (e) {
throw e;
}
).timeout(Duration(seconds: 2));
return file;
},
onError: (e) {
print('D: Bad'); //D
throw e;
}
).timeout(Duration(seconds: 2));
}
_syncRandomAccessFile() {
while(_randomAccessFile == null) {
print('Waiting on _randomAccessFile...');
}
}
void close() {
_syncRandomAccessFile();
print('D: Position: ${_randomAccessFile.positionSync()}'); //D
_randomAccessFile.setPositionSync(0); //D
print('D: Position: ${_randomAccessFile.positionSync()}'); //D
print('D: Byte: ${_randomAccessFile.readByteSync()}'); //D
int byte = DateTime.now().second; //D
print('D: Write: $byte'); //D
_randomAccessFile.writeByte(byte); //D
_randomAccessFile.close();
_randomAccessFile = null;
}
}
FileData fileData;
И это состояние домашней страницы моего приложения:
@override
void initState() {
super.initState();
fileData = FileData();
sleep(Duration(seconds: 1));
fileData.close();
}
Я ожидал бы следующую последовательность событий:
D: First
D: Local
(some or none) Waiting on _randomAccessFile...
D: Directory: <whatever>
D: Path: <whatever>
D: Stuff
D: Foo
(some or none) Waiting on _randomAccessFile...
D: Position: <whatever>
D: Write: <whatever>
D: Position: <whatever>
D: Position: 0
D: Byte: <whatever>
D: Write: <whatever>
Вместо этого я получаю:
D: First
D: Local
(a lot of) Waiting on _randomAccessFile...
(app freezes)
Я не понимаю, почему так должно быть. Очевидно, мне нужно, чтобы файл был открыт перед чтением / записью / закрытием, и мне нужно, чтобы он был в переменной экземпляра, чтобы иметь возможность использовать его как в синхронном, так и в асинхронном коде. Насколько я понимаю, будущее, возвращаемое getApplicationDocumentsDirectory()
, никогда не завершается по какой-то причине.
Я ожидаю, что это будет какое-то фундаментальное недоразумение, которое у меня было, больше всего на свете.