Сохранение и восстановление данных из файла json

Последнее обновление: 12.04.2023

Нередко приложение манипулирует различными сложными объектами, которые требуется сохранить в файл, а затем восстановить из файла. Рассмотрим, как сохранять объекты своих классов в файл и обратно считывать из файла. Одим из наиболее популярных форматов хранения и передачи информации представляет формат 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);
  }
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850