В исходном примере приложения для хранения заметок используется устаревший подход с бинарными файлами (File of TNotes), который приводит к нескольким проблемам:
"Мусорные" символы в файле - незаполненные части строк показывают случайные данные
Сложность отладки - бинарный формат нечитаем для человека
Ограниченная гибкость - трудно изменять структуру данных
type
TNotes = packed record
Title: String[255];
Content: String[255];
end;
Решение: переход на JSON
JSON (JavaScript Object Notation) - это легкий текстовый формат для хранения и передачи данных. Основные преимущества:
Читаемость (можно открыть в любом текстовом редакторе)
Гибкость (легко изменять структуру данных)
Кросс-платформенность
Поддержка в современных языках программирования
Простой пример работы с JSON в Pascal
Для работы с JSON в Free Pascal/Lazarus есть модуль fpjson. Рассмотрим базовый пример:
uses
fpjson, jsonparser;
procedure SimpleJsonExample;
var
jsonObj: TJSONObject;
jsonArray: TJSONArray;
jsonStr: String;
begin
// Создаем JSON объект
jsonObj := TJSONObject.Create;
try
// Добавляем данные
jsonObj.Add('title', 'Моя первая заметка');
jsonObj.Add('content', 'Это содержимое заметки');
jsonObj.Add('created', FormatDateTime('yyyy-mm-dd', Now));
// Преобразуем в строку
jsonStr := jsonObj.AsJSON;
ShowMessage(jsonStr);
// Сохраняем в файл
with TStringList.Create do
try
Text := jsonStr;
SaveToFile('note.json');
finally
Free;
end;
finally
jsonObj.Free;
end;
end;
Модернизация приложения заметок с использованием JSON
Вот как можно переписать исходное приложение, используя JSON:
unit JsonNotes;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, fpjson, jsonparser;
type
TNote = class
private
FTitle: String;
FContent: String;
public
property Title: String read FTitle write FTitle;
property Content: String read FContent write FContent;
end;
{ TForm1 }
TForm1 = class(TForm)
BtnAdd: TButton;
BtnDelete: TButton;
BtnSave: TButton;
BtnMod: TButton;
BtnNew: TButton;
Title: TEdit;
Label1: TLabel;
Label2: TLabel;
TitlesList: TListBox;
Content: TMemo;
procedure BtnAddClick(Sender: TObject);
procedure BtnDeleteClick(Sender: TObject);
procedure BtnModClick(Sender: TObject);
procedure BtnSaveClick(Sender: TObject);
procedure BtnNewClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TitlesListClick(Sender: TObject);
private
NotesList: TList;
procedure LoadNotes;
procedure SaveNotes;
procedure UpdateList;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
NotesList := TList.Create;
LoadNotes;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i: Integer;
begin
for i := 0 to NotesList.Count - 1 do
TNote(NotesList[i]).Free;
NotesList.Free;
end;
procedure TForm1.LoadNotes;
var
jsonData: TJSONData;
jsonArray: TJSONArray;
jsonObject: TJSONObject;
i: Integer;
note: TNote;
sl: TStringList;
begin
if not FileExists('notes.json') then Exit;
sl := TStringList.Create;
try
sl.LoadFromFile('notes.json');
jsonData := GetJSON(sl.Text);
if jsonData.JSONType = jtArray then
begin
jsonArray := TJSONArray(jsonData);
for i := 0 to jsonArray.Count - 1 do
begin
jsonObject := TJSONObject(jsonArray[i]);
note := TNote.Create;
note.Title := jsonObject.Get('title', '');
note.Content := jsonObject.Get('content', '');
NotesList.Add(note);
end;
end;
UpdateList;
finally
sl.Free;
if Assigned(jsonData) then jsonData.Free;
end;
end;
procedure TForm1.SaveNotes;
var
jsonArray: TJSONArray;
i: Integer;
note: TNote;
sl: TStringList;
begin
jsonArray := TJSONArray.Create;
try
for i := 0 to NotesList.Count - 1 do
begin
note := TNote(NotesList[i]);
jsonArray.Add(TJSONObject.Create([
'title', note.Title,
'content', note.Content
]));
end;
sl := TStringList.Create;
try
sl.Text := jsonArray.AsJSON;
sl.SaveToFile('notes.json');
finally
sl.Free;
end;
finally
jsonArray.Free;
end;
end;
// Остальные методы (BtnAddClick, BtnDeleteClick и т.д.) аналогичны оригиналу,
// но работают с NotesList вместо массива записей
end.
Альтернативные решения
Использование TJSONStreamer - более продвинутый способ работы с JSON:
procedure SaveNotesWithStream;
var
stream: TFileStream;
i: Integer;
len: Integer;
begin
stream := TFileStream.Create('notes.dat', fmCreate);
try
for i := 0 to NoteCount - 1 do
begin
// Записываем длину заголовка и сам заголовок
len := Length(Note[i].Title);
stream.WriteBuffer(len, SizeOf(len));
stream.WriteBuffer(Note[i].Title[1], len);
// Записываем длину содержимого и само содержимое
len := Length(Note[i].Content);
stream.WriteBuffer(len, SizeOf(len));
stream.WriteBuffer(Note[i].Content[1], len);
end;
finally
stream.Free;
end;
end;
Заключение
Переход с бинарных файлов на JSON в приложении для заметок дает значительные преимущества:
Читаемость данных - файлы можно просматривать и редактировать вручную
Гибкость - легко добавлять новые поля в структуру заметок
Совместимость - данные можно использовать в других приложениях
Простота отладки - проблемы с данными легко обнаружить
Для начинающих рекомендуется начать с простых примеров работы с TJSONObject и TJSONArray, а затем переходить к более сложным вариантам с использованием TJSONStreamer.
Пример кода из этой статьи можно использовать как основу для создания собственных приложений с хранением данных в формате JSON.
Статья описывает переход от использования бинарных файлов к JSON в Delphi и Lazarus для хранения заметок, демонстрируя преимущества JSON и предоставляя примеры реализации.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.