Нередко приложение манипулирует различными сложными объектами, которые требуется сохранить в файл, а затем восстановить из файла. Рассмотрим, как сохранять объекты своих классов в файл и обратно считывать из файла. Одим из наиболее популярных форматов хранения и передачи информации представляет формат json. Поэтому рассмотрим на примере сохранения и восстановления данных из файла json.
Прежде всего для работы с json нам потребуется функционал пакета dart:convert, а именно функция json.encode(), которая конвертирует данные в формат json, и функция json.decode(), которая восстанавливает данные из json.
Пусть у нас есть следующий класс Person:
class Person{ String name; int age; Person(this.name, this.age); factory Person.fromJson(Map<String, Object?> jsonMap){ return Person(jsonMap["name"] as String, jsonMap["age"] as int); } Map toJson() => { "name": name, "age": age}; @override toString() => "Name: $name \t Age: $age"; }
Для хранения данных класс Person определяет два поля: name и age. Кроме обычного конструктора класс определяет фабричный конструктор Person.fromJson()
,
который получает словарь, где ключи представляют строки, а значения - произвольные объекты, и по элементам этого словаря создает объект Person. То есть мы ожидаем,
что словарь jsonMap будет иметь два элемента с ключами "name" и "age".
Также класс Person определяет метод toJson()
, который выполняет обратную операцию - из объекта Person создает словарь Map с двумя ключами "name" и "age".
Сохраним один объект класса Person в файл json:
import 'dart:io'; import 'dart:convert'; void main() async { Person tom = Person("Tom", 38); var encoded = json.encode(tom); // преобразуем в json File file = File("person.json"); await file.writeAsString(encoded); // запись в файл print("File has been written"); } class Person{ String name; int age; Person(this.name, this.age); factory Person.fromJson(Map<String, Object?> jsonMap){ return Person(jsonMap["name"] as String, jsonMap["age"] as int); } Map toJson() => { "name": name, "age": age}; @override toString() => "Name: $name \t Age: $age"; }
Здесь прежде всего получаем код json:
var encoded = json.encode(tom);
Функция json.encode
использует метод toJson()
для получения из объекта словаря Map, который легко трансформировать в json.
Поскольку код json по сути представляет строку, то мы можем записать ее в текстовый файл. В итоге данные будут записаны в файл "person.json".
Теперь обратно считаем данные из файла в объект Person:
import 'dart:io'; import 'dart:convert'; void main() async { File file = File("person.json"); final data = await file.readAsString(); // считываем файл как строку final decoded = json.decode(data); // преобразуем в словарь Map final Person person = Person.fromJson(decoded); // создаем объект Person print(person); // Name: Tom Age: 38 }
Здесь вначале считываем данные из файла в строку с помощью метода file.readAsString()
final data = await file.readAsString();
Затем строку декодируем из формата json в объект Map
final decoded = json.decode(data);
В конце, используя фабричный конструктор, создаем объект Person:
final Person person = Person.fromJson(decoded);
Усложним задачу. Теперь пусть нам надо сохранить список объектов:
import 'dart:io'; import 'dart:convert'; void main() async { final people = [Person("Tom", 38), Person("Bob", 42), Person("Sam", 25)]; final encoded = json.encode(people); await File("people.json").writeAsString(encoded); print("Data saved"); }
Здесь сохраняется список из трех объектов в файл "people.json". В итоге в файл будут записаны следующие данные:
[{"name":"Tom","age":38},{"name":"Bob","age":42},{"name":"Sam","age":25}]
Теперь восстановим данные:
import 'dart:io'; import 'dart:convert'; void main() async { final data = await File("people.json").readAsString(); final decoded = json.decode(data); var people = []; // перебираем словарь списков и создаем по каждому словарю объект Peron for(final item in decoded){ final Person person = Person.fromJson(item); // создаем объект Person people.add(person); } // перебираем объекты Person для вывода на консоль for(final person in people){ print(person); } }
Здесь сначала считываем данные из файла в строку:
final data = await File("people.json").readAsString();
Далее конвертируем строку json в список словарей Map:
final decoded = json.decode(data);
То есть здесь decoded
представляет список List, каждый элемент которого представляет словарь Map. И нам надо из каждого такого словаря получить объект Person.
Для этого проходим по списку decoded, по каждому его элементу создаем объект Person, который далее добавляем в список people:
var people = []; // перебираем словарь списков и создаем по каждому словарю объект Peron for(final item in decoded){ final Person person = Person.fromJson(item); // создаем объект Person people.add(person); }