Как записать json для allurebox
Перейти к содержимому

Как записать json для allurebox

  • автор:

Как сделать запись в json файл?

Как реализовать запись в файл? У меня в assets есть json файл и чтение с него происходит хорошо, а вот запись как делать нигде не могу найти. Вот код:

 binding.apply < buton.setOnClickListener < write_sjon() read_json() for (i in 0..arr.size - 1) < if ((edittext1.text.toString() == arr[i]) and (edittext2.text.toString() == arr[i + 1])) < Toast.makeText(this@MainActivity, "OK", Toast.LENGTH_LONG).show() break >if (i == 6) break > > > > fun read_json() < var json: String? = null try < val inputStream: InputStream = assets.open("login.json") json = inputStream.bufferedReader().use < it.readText() >val jsonar = JSONArray(json) for (i in 0..jsonar.length() - 1) < val jsonobj = jsonar.getJSONObject(i) arr.add(jsonobj.getString("login")) arr.add(jsonobj.getString("password")) >> catch (e: Exception) < Log.e("Exception", "Json file not find") >> 

В конце еще есть метод

fun write_sjon() <> 

В него-то мне и надо добавить возможность записи в файл,желателен простой пример для понимания на примере логин:пароль

JSoN файл: [ < "login": "Pimp", "password": "123" >, < "login": "Lops", "password": "443" >, < "login": "Hos", "password": "295" >, < "login": "Kok", "password": "728" >] 

Чтение и запись в файл JSON-объекта

Эта статья научит вас парсить данные из JSON. Также вы узнаете, как читать и записывать в файл данные JSON.

За последние 5-10 лет формат JSON был одним из самых популярных способов сериализации данных (если не самым популярным). Особенно в веб-разработке. С этим форматом вы столкнетесь при работе с REST API, конфигурациями приложений или базами данных.

Несомненно, знать принципы работы JSON — очень важно. В какой-то момент вы обязательно с ним встретитесь. Возможно, вы захотите узнать, как читать и записывать JSON в файл. Все эти действия — очень простые. В этом вы убедитесь, разобрав следующие примеры.

Запись JSON в файл

Самый простой способ записать JSON в файл — использовать словарь. Они могут хранить вложенные словари, массивы, булевы значения и другие типы данных вроде целых чисел и строк. Более детальный список поддерживаемых типов данных можно найти здесь.

Во встроенной библиотеке json есть «волшебный» метод, который позволяет конвертировать словари в сериализованную JSON-строку.

import json data = <> data['people'] = [] data['people'].append(< 'name': 'Scott', 'website': 'pythonist.ru', 'from': 'Nebraska' >) data['people'].append(< 'name': 'Larry', 'website': 'pythonist.ru', 'from': 'Michigan' >) data['people'].append(< 'name': 'Tim', 'website': 'pythonist.ru', 'from': 'Alabama' >) with open('data.txt', 'w') as outfile: json.dump(data, outfile)

После импорта библиотеки json мы объявляем несколько словарей и наполняем их данными. Самая важная часть — в конце программы. Здесь мы используем оператор with , чтобы открыть файл. После этого мы используем метод json.dump , чтобы записать наши словари в файл.

Вторым аргументом может быть любой файлоподобный объект — даже если это не совсем файл. Например, сокет. Его можно открыть, закрыть и записать так же, как и файл. С подобным вариантом использования JSON вы точно столкнетесь — это важно запомнить.

Стоит упомянуть и о вариации метода json.dump — json.dumps . Этот метод позволяет вернуть JSON-строку, а не записывать ее в файл. Это может быть полезно, если вы хотите изменить JSON-строку. (например, зашифровать)

Чтение JSON из файла

Чтение JSON из файла такое же простое, как и запись. С помощью библиотеки json мы можем спарсить JSON-строку прямо из файла. В этом примере мы парсим данные и выводим их в консоль:

import json with open('data.txt') as json_file: data = json.load(json_file) for p in data['people']: print('Name: ' + p['name']) print('Website: ' + p['website']) print('From: ' + p['from']) print('')

json.load — очень важный метод, запомните его. С его помощью происходит чтение файла, парс JSON-данных. После этого все данные записываются в словарь и возвращаются вам.

Как и у json.dump , у json.load есть дополнительный метод. Он позволяет работать со строками напрямую, ведь чаще всего у вас не будет файлоподобного объекта, содержащего JSON. Как вы уже догадались, называется он json.loads . Допустим, вы вызываете конечную точку REST с помощью GET, который возвращает строку. Ее мы и можем напрямую передать в json.loads .

Параметры

При сериализации данных в JSON могут возникнуть проблемы. Например, его будет не очень удобно читать, ведь удаляются все пробелы. В большинстве случаев этот вариант вполне хорош, но порой нужно внести небольшие изменения. К примеру, добавить пробелы, чтобы JSON было удобнее читать. У json.load и json.dump есть несколько параметров, которые дают необходимую гибкость. О некоторых из них мы и поговорим.

Pretty-Printing

Сделать JSON более удобочитаемым (pretty-printing) — очень просто. Нужно лишь передать целое число в параметр indent :

import json data = <'people':[<'name': 'Scott', 'website': 'pythonist.ru', 'from': 'Nebraska'>]> json.dumps(data, indent=4) < "people": [ < "website": "pythonist.ru", "from": "Nebraska", "name": "Scott" >] >

Это довольно полезно. Особенно если вам часто приходится читать JSON во время работы. Также вы можете использовать использовать команду json.tool прямо в командной строке. Если вы хотите удобочитаемый JSON, наберите в командной строке следующий код:

$ echo '<"people":[<"name":"Scott", "website":"pythonist.ru", "from":"Nebraska">]>' | python -m json.tool < "people": [ < "name": "Scott", "website": "pythonist.ru" "from": "Nebraska", >] >

Сортировка

В JSON объект определяется следующим образом:

Объект — это неупорядоченный набор пар ключ/значение.

То есть, порядок не гарантируется. Но навести его реально. Сделать это можно с помощью передачи True в параметр sort_keys в методах json.dump или json.dumps .

import json data = <'people':[<'name': 'Scott', 'website': 'pythonist.ru', 'from': 'Nebraska'>]> json.dumps(data, sort_keys=True, indent=4) < "people": [ < "from": "Nebraska", "name": "Scott", "website": "pythonist.ru" >] >

ASCII-текст

По умолчанию json.dump проверяет, имеет ли ваш текст в словаре кодировку ASCII. Если присутствуют символы, отличные от ASCII, они автоматически экранируются. Это показано в следующем примере:

import json data = jstr = json.dumps(data, indent=4) print(jstr)

Но это не всегда приемлемо. Во многих случаях вы бы хотели сохранить символы Unicode нетронутыми. Для этого нужно передать в параметр ensure_ascii значение False .

jstr = json.dumps(data, ensure_ascii=False, indent=4) print(jstr)

Записать в файл JSON

Выходной коннектор Записать в файл JSON может использоваться для записи событий GeoEvent, интерпретированных как универсальный файл JSON, в файл JSON.

Примечания по использованию

  • Этот выходной коннектор связывает исходящий адаптер универсального файла JSON с исходящим транспортом файла.
  • Зарегистрированная папка сервера может быть задана с помощью абсолютного или относительного пути.
  • Если используется относительный путь, учетной записи службы Windows, под которой запущен GeoEvent Server , требуется разрешение на чтение/запись в папку.
  • Рекомендуется использовать абсолютные пути, например, C:\GeoEvent\input для свойства Папка .
  • Свойство Подпапка позволяет указать подпапку, связанную с зарегистрированной папкой сервера.
  • При перезапуске выхода GeoEvent Server создаст новый файл в зарегистрированной системной папке.
  • В зависимости от скорости и объема обрабатываемых событий GeoEvent рекомендуется увеличить Размер перехода к следующему файлу (КБ) на значение больше значения по умолчанию 1 , чтобы избежать создания каскада файлов JSON, с которыми Windows не сможет справиться.
  • Этот выходной коннектор представляет каждую запись события как отдельный объект JSON в файле JSON. С установленными по умолчанию Верхним колонтитулом файла , Нижним колонтитулом файла и Разделителем событий , каждый объект JSON организуется в корректный массив JSON с элементами, разделенными запятой. Открывающая квадратная скобка Верхнего колонтитула файла определяет начало массива JSON, а закрывающая квадратная скобка Нижнего колонтитула файла определяет конец массива JSON. Запятая Разделителя событий разделяет каждый объект JSON.

Параметры

Описательное имя выходного коннектора, используемое для справки в GeoEvent Manager.

Зарегистрированная системная папка, под которой будут создаваться и записываться файлы.

Префикс имени файла

Задает имя выходного файла, который GeoEvent Server будет создавать и в который будут записываться данные. К имени файла добавляется дата / время первого создания файла. По умолчанию – output .

Пример: префикс имени файла output , созданного 19 марта 2019 года в 2:30:05 pm, в результирующем имени файла будет output2019-03-19_14-30-05.out .

Указывает имя подпапки (или подкаталога) относительно зарегистрированной системной папки, под которой будут создаваться и записываться файлы. Это свойство следует оставить пустым, если вложенная папка не существует. Для этого свойства отсутствует значение по умолчанию.

Пример: при указании зарегистрированной системной папки как C:\GeoEvent и подпапок как output GeoEvent Server создаст свой файл в C:\GeoEvent\output предполагая, что путь к файлу существует и доступен учетной записью службы Windows, запускающей ArcGIS GeoEvent Server .

Расширение файла, используемое при создании новых файлов. По умолчанию для этого свойства используется json , что означает, что GeoEvent Server создаст файл JSON.

Метод перехода к следующему файлу

  • По размеру – GeoEvent Server прекратит запись в текущий файл при достижении заданного порогового значения размера файла. При достижении порогового значения будет создан новый файл.
  • По времени – GeoEvent Server прекратит запись в текущий файл при достижении заданного порогового значения времени. При достижении порогового значения будет создан новый файл.

Размер перехода к следующему файлу (КБ)

Задает максимальный размер файла в килобайтах (КБ), который может быть достигнут до того, как GeoEvent Server прекратит запись. После того как максимальный размер файла достигнут, GeoEvent Server создаст новый файл, и продолжит запись в него. По умолчанию – 1 килобайт.

Это свойство показывается, когда для свойства Метод перехода к следующему файлу задано значение По размеру , и скрыто, если выбрано значение По времени

Частота перехода к следующему файлу

  • Каждый день – GeoEvent Server прекратит запись в текущий файл и начнет запись в новый файл каждый час.
  • Каждый день – GeoEvent Server прекратит запись в текущий файл и начнет запись в новый файл каждый день.
  • Каждый месяц – GeoEvent Server прекратит запись в текущий файл и начнет запись в новый файл каждый месяц.

Это свойство показывается, когда для свойства Метод перехода к следующему файлу задано значение По времени , и скрыто, если выбрано значение По размеру

Возраст очистки файлов (минуты)

Указывает возраст в минутах, с которого старые файлы будут обрабатываться в соответствии с Методом очистки файлов . По умолчанию – 4320 минут.

Пример: каждые 3 дня (4320 минут) файлы будут либо удалены или помещены в архив.

Метод очистки файлов

  • Удалить – файл, достигший возраста, указанного в свойстве Возраст очистки файла (минуты) будет удален.
  • Архивировать – файл, достигший возраста, указанного в свойстве Возраст очистки файла (минуты) будет помещен в архив.

Зарегистрированная системная папка, под которой будут архивироваться файлы, достигшие возраста очистки файлов (минуты) . Для этого свойства отсутствует значение по умолчанию.

Это свойство показывается, когда для Метода очистки файлов задано значение Архивировать , и скрыто, если выбрано значение Удалить

Подпапка относительно Папки архива , под которой будут архивироваться файлы, достигшие возраста очистки файлов (минуты) . Оставьте это свойство неуказанным, если подпапка для архивирования файлов отсутствует. Для этого свойства отсутствует значение по умолчанию.

Это свойство показывается, когда для Метода очистки файлов задано значение Архивировать , и скрыто, если выбрано значение Удалить

  • Да – исходный JSON будет форматироваться (подготавливаться).
  • Нет – исходный JSON не будет форматироваться.

Верхний колонтитул файла

Символ(ы), который будет вставлен в начале каждого файла JSON. GeoEvent Server может использовать любой обычный символ ASCII или комбинацию символов в качестве верхнего колонтитула файла. По умолчанию – [ (левая скобка).

Нижний колонтитул файла

Символ(ы), который будет вставлен в конце каждого файла JSON. GeoEvent Server может использовать любой обычный символ ASCII или комбинацию символов в качестве нижнего колонтитула файла. По умолчанию – ] (правая скобка).

Символ, который будет использоваться для разделения каждой записи события в файле JSON. GeoEvent Server может применять любой обычный символ ASCII в качестве разделителя событий. По умолчанию – , (запятая).

В этом разделе
  1. Примечания по использованию
  2. Параметры

Запись данных в формате JSON

В одной из моих программ понадобилась запись данных в формате JSON. Вкратце — XML-подобный формат, вполне подходит на замену Windows INI-файлам или тому же XML. Удобен тем, что поддерживает массивы и вложенность собственных структур, но при этом не замусоривает файл данных своими тегами до полной нечитабельности человеком. Вот пример файла данных:

< "Comment":"My comment", "Count":10, "DiskParam": < "DB":10.000000, "DBAngle":1.234000 >, "Range":true, "Blades": [ < "Caption":"A", "Value":65 >, < "Caption":"B", "Value":66 >, < "Caption":"C", "Value":67 >], "Slots": [ 0,1,2 ] >

Формат довольно простой, вполне можно работать с ним без всяких библиотек. Поэтому первоначально за запись отвечал примерно такой участок кода:

 fprintf(pOut, "<\n"); fprintf(pOut, " \"Comment\":\"%s\"", Header->Comment); fprintf(pOut, ",\n \"NumSt\":%d", Header->NumSt); //Пропущено немного кода fprintf(pOut, ",\n \"DBMax\":%lf", Header->DBMax); fprintf(pOut, ",\n \"Range\":%s", Header->Range?"true":"false"); fprintf(pOut, ",\n \"Blades\":\n ["); for(int i=0; iCount; i++) < TElement &e=Element[i]; fprintf(pOut, i?",\n "); > fprintf(pOut, "\n ]"); //Пропущено много кода fprintf(pOut, "\n>");

Корявенько, хотя вполне работоспособно. Но программа активно дорабатывалась, формат данных менялся по 5 раз на дню и остро встала проблема отслеживания всех изменений. Несмотря на некоторое форматирование исходника было тяжело не забыть закрыть какой-нибудь тег или правильно напечатать нужное число пробелов для форматирования уже собственно файла данных. Даже в приведенном фрагменте перед публикацией обнаружилась ошибка, не ставилась запятая между элементами массива.

Решил я этот техпроцесс слегка механизировать и создать микробиблиотеку для работы с JSON.

Что я хотел? Чтобы в своей программе я писал что-то на псевдоязыке:

Key("Ключ1"); Value("Значение1"); Key("Ключ2"); Value("Значение2"); Object("Объект1"); Key("Ключ3"); Value("Значение3"); //Ключ3,Ключ4 являются элементами Объект1 Key("Ключ4"); Value("Значение4"); Array("Массив1"); Key("Ключ5"); Value("Значение5"); //Ключ5. КлючN являются элементами Массив1 Key("Ключ6"); Value("Значение6"); . Key("КлючN"); Value("ЗначениеN");

А компилятор/программа пусть сами учтут отступы, которые определяют структуру файла данных. В нужный момент подставят открывающий и, главное, закрывающий тег. Дело осложнялось тем, что внутри этого скрипта хотелось использовать конструкции C++, например циклы внутри массивов.

После нескольких дней непрерывной мозговой осады этой проблемы нашлось довольно изящное решение. Для контроля за вложением друг в друга JSON-сущностей и своевременного закрытия тегов используется область видимости переменных. Все очень просто, создается экземпляр одного из классов TJson*** — записывается ключ и открывающий тег и все следующие созданные объекты считаются его вложениями. Уничтожается экземпляр — ставится закрывающий тег.

#define TCF_USED 1 class TTagCloser < public: TTagCloser *Owner; static TTagCloser *Current; static int Depth; int Flags; int Count; int operator()()TTagCloser() ~TTagCloser() >; TTagCloser *TTagCloser::Current=NULL; int TTagCloser::Depth=-1;

Простой класс, все назначение которого — временно связать порожденные объекты в некое подобие дерева. Для чего нужен перегруженный operator() будет понятно чуть позже.

У этого класса есть наследник, в котором заложен базовый функционал записи в JSON-формате. Программист должен только переопределить функции Write***.

#define TCF_OBJECT 4 #define TCF_ARRAY 2 class TJsonTagCloser:public TTagCloser < public: void WriteTab(); void WriteInt(int); void WriteDouble(double); void WriteStr(char *); TJsonTagCloser(char *Key); >; //---------------------------------------------------------------------------- TJsonTagCloser::TJsonTagCloser(char *Key):TTagCloser() < if(Owner) < if(Owner->Count) WriteStr(","); if(Owner->Flags&TCF_ARRAY) < if(!Owner->Count) WriteTab(); > else < WriteTab(); WriteStr("\""); if(Key) WriteStr(Key); WriteStr("\":"); >Owner->Count++; > >

Функция WriteTab() введена в программу удобства гиков, любящих лазить в файлы данных «Блокнотом». Она должна записать в файл данных перевод строки и число пробелов, соответствующее глубине вложения (TTagCloser::Depth). Если бы форматирование не было нужно, то функция выродилась бы в WriteTab().

У меня в тестовом примере функции Write*** определены так:

#include void TJsonTagCloser::WriteTab() void TJsonTagCloser::WriteInt(int Value) void TJsonTagCloser::WriteDouble(double Value) void TJsonTagCloser::WriteStr(char *Value)

JSON-формат предполагает наличие в потоке данных Объектов (смахивают на СИшные структуры), Массивов (они и в Африке массивы) и просто пар «Ключ: Значение». Все это многообразие может быть перемешано и вложено друг в дружку, например в паре «Ключ: Значение» Значением может быть Массив Объектов. Для работы с этими сущностями созданы следующие классы:

class TJsonArray:public TJsonTagCloser < public: TJsonArray(char *Key); ~TJsonArray(); >; class TJsonObject:public TJsonTagCloser < public: TJsonObject(char *Key); ~TJsonObject(); >; class TJsonValue:public TJsonTagCloser < public: TJsonValue(char *Key, int Value):TJsonTagCloser(Key)TJsonValue(char *Key, double Value):TJsonTagCloser(Key) TJsonValue(char *Key, bool Value):TJsonTagCloser(Key) TJsonValue(char *Key, char *Value); >; TJsonArray::TJsonArray(char *Key):TJsonTagCloser(Key) < Flags|=TCF_ARRAY; if(Owner && (!(Owner->Flags&TCF_ARRAY) || Owner->Count>1)) WriteTab(); WriteStr("["); > TJsonArray::~TJsonArray() < WriteTab(); WriteStr("]"); >//---------------------------------------------------------------------------- TJsonObject::TJsonObject(char *Key):TJsonTagCloser(Key) < Flags|=TCF_OBJECT; if(Owner && (!(Owner->Flags&TCF_ARRAY) || Owner->Count>1)) WriteTab(); WriteStr(" <"); >TJsonObject::~TJsonObject() < WriteTab(); WriteStr(">"); > TJsonValue::TJsonValue(char *Key, char *Value):TJsonTagCloser(Key) < if(Value) < WriteStr("\""); WriteStr(Value); WriteStr("\""); >else WriteStr("null"); >

Для удобства использования библиотеки в своей программе определены макросы:

#define ARRAY(k) for(TJsonArray array(k); array();) #define OBJECT(k) for(TJsonObject object(k); object();) #define VALUE(k,v)

Вот и добрались до перегруженного operator(). Он нужен для однократного выполнения тела цикла for, то есть в первый вызов он возвращает true, а в последующие — false.

А вот так в теле программы выглядит скрипт, на котором пишется заполнение файла данных:

void main() < OBJECT("") < VALUE("Comment", "My comment"); VALUE("Count", 10); OBJECT("DiskParam") < VALUE("DB", 10.0); VALUE("DBAngle", 1.234); >VALUE("Range", true); ARRAY("Blades") < for(int i='A'; i> ARRAY("Slots") for(int i=0; i >

Как выглядит сформированный этой программой JSON-файл можно посмотреть в начале статьи. Все запятые проставлены, все скобочки закрыты когда нужно, в каждой строке нужное количество ведущих пробелов — красота!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *