Как прочитать json файл scala

Обновлено: 06.07.2024

и в этих папках у меня есть файлы, которые я должен прочитать. Вот код:

почему ответ Андреаса Ноймана не был принят, если у вас есть дополнительный вопрос, прокомментируйте его. -1.

Ресурсы в Scala работают точно так же, как и в Java. Лучше всего следовать лучшим практикам Java и размещать все ресурсы в файлах src/main/resources и src/test/resources .

Пример структуры папок:

Для чтения ресурсов объект Source предоставляет метод fromResource .

Для чтения ресурсов вы можете использовать getClass.getResource и getClass.getResourceAsStream .

Чтобы избежать неполадок Java NPE, примите во внимание:

Имейте в виду, что getResourceAsStream также отлично работает, когда ресурсы являются частью jar- файла , getResource , который возвращает URL-адрес, который часто используется для создания файла, может привести к проблемам там.

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

Какие проблемы могут возникнуть при использовании getResource и преобразовании его в файл? Можете дать ссылку? Этот код, вероятно, оставляет открытым обработчик для getResourceAsStream. Спасибо! Типы байтов не совпадают в разделе « Более подробная информация об ошибках» (2.12.x) . А что с утечками памяти? Разве ресурс не должен быть закрыт?

Для Scala> = 2.12 используйте Source.fromResource :

Важно: с Source.fromResource вами не ставьте начальную косую черту, которая у вас есть getResourceAsStream .

введите описание изображения здесь

РЕДАКТИРОВАТЬ: Кредит оригинальному автору. См. Полный блог здесь

При копировании с веб-сайта, пожалуйста, разместите ссылку на первоначального автора. Отдайте должное, где это необходимо. Ссылка

Для Scala 2.11 , если getLines не делает именно то, что вы хотите, вы также можете скопировать файл из jar в локальную файловую систему.

Вот Snippit , который считывает двоичную Google P12 - формат ключ API из / ресурсов, пишет он в / TMP, а затем использует строку пути файла в качестве входных данных для свеч Google-таблиц записи .

В мире sbt-native- packager и sbt-assembly копирование на локальное также полезно с тестами масштабных двоичных файлов. Просто вытолкните их из ресурсов на локальные, запустите тесты, а затем удалите.


Данный пост входит в серию статей на тему работы с JSON в Scala и в нем будет рассмотрена работа с библиотекой Play Json (github, документация). Код основного примера и каркаса приложения можно посмотреть в репозитории на github.

Данная библиотека была выделена из веб-фреймворка Play, который входит в Typesafe Reactive Platform и для парсинга JSON строк использует java-библиотеку Jackson. Для того, что бы начать работать с библиотекой play json необходимо указать ее в качестве зависимости в вашем файле build.sbt:

И написать 2 строчки импорта:

Рассматривать возможности данной библиотеки я буду на основе примера описанного в заглавном посте серии, с которым необходимо ознакомится для полного понимания сути происходящего. Поэтому для начала, рассмотрим то, что предлагает нам библиотека Play Json, а затем как это использовать в рамках нашего примера.

Play Json: Основные методы

Для представления типов данных JSON в пакете play.api.libs.json существуют следующие типы данных:

Как видно из листинга, все эти типы данных расширяют класс JsValue , который является супертипом для всех других JSON типов. Именно этот тип данных кодирует обобщенное понятие JSON, поэтому им мы и конкретизируем абстрактный член типа в трейте JsonLibrary . Чтобы реализовать основную функциональность нашего трейта, посмотрим что нам предлагает содержащий статические методы объект Json :

Итак, для того чтобы разобрать строку представляющую json, необходимо просто передать ее в качестве параметра методу parse , обратно мы получим значение типа JsValue .

Для того, чтобы конвертировать JsValue обратно в строковое представление, необходимо передать значение этого типа в метод stringify .

С оставшимися двумя методами для сериализации/десериализации все немного сложнее:

Для того, что бы конвертировать значение JsValue в класс нашей модели (десериализовать), мы передаем это значение в метод fromJson и на выходе получаем значение типа JsResult[T] , где T это тип модели. Конвертировать значение типа JsValue в другой тип можно так же воспользовавшись методом validate трейта JsValue , который так же возвращает значение типа JsResult[T] :

Так что же представляет из себя тип JsResult ? JsResult[T] это монадический тип, который может быть либо JsSuccess[T] содержащий результат конвертации, в том случае если конвертация была удачной, либо JsError[T] в обратном случае и содержать список всех ошибок встреченных при конвертировании. И так как это монадический тип, он содержит соответствующие методы (flatMap, map, …). Вкратце, в случае успешного конвертирования JsResult будет содержать экземпляр класса нашей модели, в обратном случае набор ошибок с указанием на каком этапе конвертирования эти ошибки встретились. Мы еще рассмотрим JsResult более подробно позже, пока же достаточно знать, что мы можем конвертировать значение это типа в значение типа Option[T] при помощи метода asOpt .

Для сериализации класса в JSON передаем экземпляр класса в качестве параметра методу toJson и на выходе получаем значение JsValue . Вся загвоздка с методами сериализации/десериализации в том, что у них есть дополнительный неявный список параметров, в котором передаются экземпляры классов Reads[T] и Writes[T] соответственно. Именно эти классы знают как правильно конвертировать типы Scala в JsValue и обратно. В Play json уже содержатся неявные (де)сериализаторы для основных типов данных Scala ( DefaultWrites и DefaultReads ). Но про то, как конвертировать экземпляры наших классов Play Json ничего не известно. Поэтому мы должны написать соответствующие неявные (де)сериализаторы самостоятельно и обеспечить их присутствие в области видимости там где они потребуются. Прежде чем это сделать, давайте посмотрим на код трейта PlayJson реализующий интерфейс JsonLibrary :

В этой реализации нет ничего особенного, мы просто используем методы описанные выше. Единственная неоговоренная строка - import PlayJson._ . Она производит импорт содержимого объекта-компаньена PlayJson . В нем мы определим все необходимые неявные значения для конвертирования экземпляров наших кейс классов, данным импортом мы вводим их в область видимости, что бы они могли быть подхвачены методами нуждающимися в них. Что же содержит объект PlayJson ? На самом деле совсем немного строк кода. Но для того, что бы написать их придется изучить немного теории.

Play Json: Reads, Writes, Format и JsPath

Итак мы выяснили, что для того, чтобы конвертировать JsValue в другой тип Scala и обратно нам необходимо предоставить в область видимости соответствующие значения Reads[T] и Writes[T] где T класс модели. Как мы увидим позже, эти конвертеры можно объединить. Но начнем рассматривать все по порядку, а для этого нам нужно познакомиться еще с одним парнем - JsPath .

JsPath

JsPath это набор узлов которые надо обойти в структуре JsValue , чтобы получить значение. Попросту говоря, JsPath представляет собой путь до конкретного значения в json объекте, это практически тоже самое что и XPath для XML. Давайте посмотрим на определение JsPath :

Как видно из листинга JsPath это список узлов пути List[PathNode] и набор операций над этим списком. Методы \ и \\ имеют две версии. Это нужно для того, что бы можно было сформировать путь используя как строки ( JsPath \ "key1" ), так и символы ( JsPath \ 'key1 ). Оба этих метода и первый метод apply формируют новый путь добавляя узлы соответствующих типов (они все расширяют PathNode ) к исходному пути. Вторая версия apply применяет значение типа JsValue к сформированному пути, т.е. берем первый узел в пути и из переданного json-значения выбираем все дочерние ключи соответствующие этому узлу. Получается список значений JsValue (отобранные ключи). Затем берется следующий узел и из полученного списка выбирается все дочерние ключи, соответствующие новому узлу и так далее. Когда узлы в пути закончатся, то итоговый список значений JsValue как раз и будет результатом. Давайте посмотрим на примере и сформируем такой путь:

А теперь попробуем применить к этому пути различные json объекты:

Итак, для того что бы сформировать путь, нам надо начать с объекта JsPath , который представляет корневой элемент пути и продолжить добавляя к нему соответствующие узлы, при помощи описанных выше методов. Для большего удобства и лучшего визуального выделения в объекте пакета json для объекта JsPath определен алиас: __ так что путь из предыдущего примера можно переписать так:

Теперь, когда мы научились формировать путь, можно перейти к написанию непосредственно конвертеров. Reads

Конвертеры Reads[T] используются для десериализации из JsValue в какой-нибудь другой тип T , например в класс модели Listing . Reads[T] можно комбинировать и вкладывать друг в друга, что бы получить более сложные конвертеры Reads[T] . Например для того, что бы получить десериализатор кейс класса Counters , нам необходимо объединить четыре десериализатора из JsValue в Int. А для того, что бы написать десериализатор для класса Link нам придется вложить десериализатор класса Counters . Давайте, напишем десериализатор для класса Counters . Так как все поля этого класса имеют стандартный тип Scala, это будет довольно просто и библиотека Play Json предлагает несколько способов сделать задуманное. Во первых, мы можем воспользоваться JsPath и его методами read и readNullable :

Данные методы принимают в качестве параметра неявный конвертер типа Reads[T] и применяют его к значению извлеченному по указанному пути. Метод readNullable полезен в случае если значение по указанному пути равно null или не найдено, в таком случае он вернет None . Например следующий код:

Применит к значению ключа before неявный конвертер в тип String, который предоставляется Play Json:

Итак, мы можем извлекать и конвертировать отдельные значения. Для того, что бы преобразовать эти отдельные значения в более сложный тип, например класс Counters необходимо скомбинировать конвертеры при помощи операции and или

(по сути and просто вызывает

Более кратко все это можно записать следующим образом:

Понимая принцип создания сложных конвертеров из комбинации простых, последний листинг выглядит довольно простым. Однако библиотека Play Json предоставляет еще более простой способ. Создать десериализатор для вашей модели можно так же при помощи удобного метода reads объекта Json. Данный метод использует макросы введенные в Scala 2.10:

Вот и все. Одна строка. Но у этого метода есть ряд ограничений: - нельзя перегружать метод apply у кейс класса в объекте компаньене, потому что макрос не сможет выбрать между несколькими методами apply - функции apply (и unaply в случае write ) должны иметь соответствующие входные/выходные типы. У кейс классов это предоставляется автоматически, а для трейтов необходимо будет написать соответствующие методы apply и unaply . Обратите внимание как обрабатывается модель Listing , ниже - Json макрос умеет обрабатывать следующие обобщенные типы Option , Seq , List , Set и Map[String, _] . В случае остальных придется отказаться от использования макросов.

Наименование полей данных в модели должно соответствовать наименованиям полей в json объекте. Давайте теперь напишем десериализаторы для остальных моделей, начнем с модели для ссылок:

Для поля title мы воспользовались неявным конвертером предоставляемым библиотекой. А для конвертирования поля url , я воспользовался удобным методом map и преобразовал конвертер строки в конвертер класса URL . Поля содержащиеся в классе Counters , иерархически находятся на одном уровне с полями title и url , поэтому конвертеру мы указываем просто путь (__ \ "data") , и так как ранее мы уже написали неявный конвертер для типа Counters никаких преобразований больше не требуется. Хотя, отдельный неявный конвертер для Counters можно было и не писать, а просто передать явно в качестве параметра:

Теперь настала очередь десериализатора для последней модели:

Здесь стоит отметить два момента. Во-первых, конвертер для поля children . Так как значением этого поля является массив объектов, соответствующих модели Link в нашем представлении, мы конвертируем его в коллекцию ссылок Seq[Link] . Это работает так как в play json уже есть неявный сериализатор для коллекций. Во-вторых, это способ формирования экземпляра нашей модели. Из-за того, что модель Listing имеет поле id , которое отсутствует в json, но должно быть задано при создании экземпляра, мы не можем использовать функцию apply модели. Вместо этого мы передаем лямбда выражение, формирующее функцию принимающую три параметра и возвращаю экземпляр класса Lisitng . Более развернуто это можно записать следующим образом:

Итак, с десериализаторами мы закончили переходим к написанию сериализаторов.

Writes

С сериализаторами все будет немного проще. Дело в том, что реализация сериализатора практически не отличается от десериализатора. Начнем с модели Counters . Когда мы писали для нее десериализатор, то в конце концов воспользовались методом reads[T] объекта Json, основанным на макросах. Как вы наверно догадались, существует такой же метод и для сериализатора:

Не будем реализовывать его в качестве отдельного неявного значения, а просто передадим его в качестве параметра при реализации сериализатора для модели Link :

Итак, перечислим основные отличия. Для поля url мы создаем новый конвертер Writes[URL] и реализуем логику конвертирования в методе writes, так как к экземпляру класса Write[T] метод map не применим. Для того, что бы сформировать из экземпляра нашей модели, несколько значений (те члены класса которые необходимо сериализовать), мы используем функцию unapply, но так как результат этой функции будет Option[(String, URL, Counters)] вместо ( String , URL , Counters ) мы трансформируем ее при помощи функции unlift . И в заключении сериализатор для модели Listing :

Единственное отличие здесь это то, что вместо метода unapply мы передаем лямбду возвращающую только три поля и игнорирующую поле id , которое не требует сериализации. И вот наконец-то мы разобрались с сериализаторами и десериализаторами и казалось бы на этом можно ставить точку. Однако Play Json предоставляет возможность объединить написание сериализатора и десериализатора в одном классе.

Format

Format[T] это просто смесь из конвертеров Reads[T] и Writes[T] . Для того, что бы создать Format[T] можно воспользоваться, например, методом на основе макросов:

Или можно воспользоваться уже имеющимися конверторами Reads и Writes:

Также можно написать конвертеры с нуля, воспользовавшись комбинаторами:

Итак, разобравшись с теорией, вернемся к объекту PlayJson нашего приложения. Вот его реализация:

Обратите внимание на порядок объявления неявных значений. Так как linkFormat используется при создании listingFormat , в таком виде он обязательно должен предшествовать созданию listingFormat . Иначе, при выполнении тестов, вы получите не очень информативное исключение времени исполнения - java.lang.NullPointerException

Тесты

После того как мы разобрались как сериализовывать/десериализовывать данные при помощи библиотеки Play Json. Давайте реализуем и запустим тесты. Для этого просто создадим две спецификации, расширив соответствующие спецификации для тестов функциональности и тестов производительности:

Запустим и посмотрим на результаты:


Posted by Golovko Aleksander Mar 9 th , 2014 5:13 pm json, play json, scala

Я пытаюсь извлечь данные из файла JSON, который выглядит следующим образом :

Я хотел бы сделать это с помощью библиотеки play JSON. Я придумал этот код :

Однако этот код дает JsError : List(ValidationError(validate.error.missing-path,WrappedArray())).

Что, насколько я понимаю, просто означает, что какой-то путь пропал. Я попытался прочитать только одну категорию, и это сработало нормально, я пытаюсь прочитать элемент, не пытаясь получить категории, и здесь снова все прошло нормально. Поэтому я думаю, что проблема заключается в чтении списка элементов. Я был бы очень признателен, если бы вы помогли мне с этим.

1 ответ

Я пытаюсь прочитать файл csv с помощью Scala и сохранить выходные данные в виде списка Json ( list(json.obj) ). Вот мой код: def index = Action < Logger.info(Application startup. ) var posts = List(Json.obj()) var finalPost = List(Json.obj()) val bufferedSource =.

Я учусь spark в Scala. У меня есть файл JSON следующим образом: [ < name: ali, age: 13, phone: 09123455737, sex: m >, < name: amir, age: 24, phone: 09123475737, sex: m >] и есть только этот код: val sqlContext = new org.apache.spark.sql.SQLContext(sc) val jsonFile =.

Путь относителен. categoryRead путь js должен быть относительным. Например, _ \ xxx

Похожие вопросы:

Вот фрагмент из моего gruntjs. Я передаю цель через параметр командной строки. Файл json, который я читаю в настройках, содержит конфигурационные данные, необходимые для моих задач.

Я читаю файл в scala с помощью def fileToString(that:String):String= < var x:String= for(line <- Source.fromFile(that).getLines)< x += line + \n >x > Это прекрасно работает для файла scala. Но в.

В Scala для чтения текстового файла и загрузки его в массив обычно используется следующий подход: scala.io.Source.fromFile(file.txt).getLines.toArray Особенно для очень больших файлов, есть ли более.

Я пытаюсь прочитать файл csv с помощью Scala и сохранить выходные данные в виде списка Json ( list(json.obj) ). Вот мой код: def index = Action < Logger.info(Application startup. ) var posts =.

Я учусь spark в Scala. У меня есть файл JSON следующим образом: [ < name: ali, age: 13, phone: 09123455737, sex: m >, < name: amir, age: 24, phone: 09123475737, sex: m >] и есть только этот код: val.

Я пишу UI тестов для iOS приложений. Я хочу прочитать данные из локального файла json. Я использую следующий код, чтобы получить путь к моему файлу json: func testExample() < readJSON() >func.

Чтение заголовков из файла JSON и установка в качестве кортежей для заголовка в вызове API с помощью воспроизведения в SCALA У меня есть файл Json, который имеет заголовки и тело, как это: Имя.

JSON файл: нужно перебрать каждый элемент с помощью scala.read файла JSON в scala и перебрать каждый элемент & и добавить к нему конкретный список. Ввод:

Я хотел бы прочитать файл HDFS в scala. Это текстовый файл, и я хотел вставить значение поля по умолчанию в каждую строку. Как мне прочитать файл hdfs как поток строка за строкой? У меня есть этот.

Я часто ловлю себя на том, что читаю большой файл JSON (обычно массив объектов), затем манипулирую каждым объектом и записываю обратно в новый файл. Чтобы достичь этого в узле (по крайней мере.

OS X El Capitan 10.11.6 Spark 2.2.0 Scala 2.11.8 Конкретный файл JSON, который я пытаюсь прочитать в Spark, можно найти здесь . Когда я использую приведенный ниже код, он обеспечивает вывод одного столбца того, что выглядит как все значения столбцов вместе: val test =.

Я пытаюсь прочитать файл кодировки utf-8 в Spark Scala. Я делаю это val nodes = sparkContext.textFile(nodes.csv) где данный файл csv находится в UTF-8, но spark преобразует неанглийские символы в ? , как мне заставить его читать фактические значения? Я попробовал его в pyspark, и он отлично.

Я предлагаю использовать wholeTextFiles для чтения файла и применить некоторые функции для его преобразования в однострочный формат JSON.

У вас должно быть окончательное действительное dataframe как

И действителен schema как

Spark 2.2 введена опция multiLine, которая может использоваться для загрузки JSON (не JSONL) файлов:

Вероятно, это как-то связано с объектом JSON, хранящимся в вашем файле, не могли бы вы распечатать его или убедиться, что это тот, который вы указали в вопросе? Я спрашиваю, потому что я взял этот, и он работает просто отлично:

Обратите внимание, что файл, предлагаемый в качестве файла json, не является типичным файлом JSON. Каждая строка должна содержать отдельный автономный допустимый объект JSON.

У меня есть текстовый файл, содержащий json строк, структура которого приведена ниже. Мне нужно прочитать его как JSON с spark и преобразовать в класс case с приведенным ниже кодом scala. Мне нужны только определенные поля, заданные в классе.

Похожие вопросы:

Я видел различные вопросы spark и avro (в том числе, как я могу загрузить Avros в Spark, используя схему на борту файла(файлов) Avro? ), но ни одно из решений не работает для меня со следующим.

У меня есть файл фиксированной длины ( пример показан ниже), и я хочу прочитать этот файл, используя DataFrames API в Spark, используя SCALA(а не python или java). Используя DataFrames API, есть.

Я хочу прочитать файл JSON и создать класс/объект, который сохранил все метки и значения из каждого JSON vector/record., затем я хочу изменить некоторые значения (или структуру JSON) и получить этот.

OS X El Capitan 10.11.6 Spark 2.2.0 Scala 2.11.8 Конкретный файл JSON, который я пытаюсь прочитать в Spark, можно найти здесь . Когда я использую приведенный ниже код, он обеспечивает вывод одного.

Я пытаюсь прочитать файл кодировки utf-8 в Spark Scala. Я делаю это val nodes = sparkContext.textFile(nodes.csv) где данный файл csv находится в UTF-8, но spark преобразует неанглийские символы в .

У меня есть текстовый файл, содержащий json строк, структура которого приведена ниже. Мне нужно прочитать его как JSON с spark и преобразовать.

Я начинаю с spark, и у меня есть к вам вопрос. Я хочу прочитать файл. Я вижу какой-то учебник, и они говорят, чтобы сделать это : val rib = spark.read.format(csv).option(header, true).load(<a.

Я пытаюсь прочитать конфигурационный файл json в свой проект scala. Формат json выглядит следующим образом: < parameters: [ < name: testInteger, type: Integer, value: 10 >, < name: testString, type.

У меня есть два набора данных, которые находятся в формате TSV. Я хочу прочитать оба файла TSV в spark scala и выполнить анализ. Файл 1 содержит данные августа, а файл 2-Данные сентября. Как я могу.

Читайте также: