Подход функционального программирования для потоков ввода/вывода Java

Я использую Java DataInputStream с scala для парсинга некоторого простого двоичного файла (который является очень плох exprerience из-за отсутствия неподписанных типов, даже в scala, но это - другая история).

Однако я нахожу меня вынужденным использовать изменяемую структуру данных, так как потоки Java являются по сути объектами сохранения состояния.

Что хороший дизайн должен перенести потоки Java с хорошей функциональной структурой данных?

5
задан Elazar Leibovich 1 June 2010 в 07:34
поделиться

3 ответа

В настоящее время в проекте прогресс, направленный на создание API ввода-вывода для Scala: scala IO Он вдохновлен Java 7 NIO API. Это все еще WIP, но вы можете почерпнуть из него интересные идеи. Также есть несколько примеров того, как его использовать, которые можно найти здесь

5
ответ дан 14 December 2019 в 04:31
поделиться

Взгляните на IO Monad от Haskell для чисто функционального подхода.

Прагматическая реализация Scala будет реализовывать Iterator / Iterable на основе Stream. Например, scala.io.Source поддерживает это.

1
ответ дан 14 December 2019 в 04:31
поделиться

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

Можно притвориться, что вся вселенная является входным (и выходным) параметром, и создать "функциональный" аналог, но я никогда не видел четкой демонстрации того, что это имеет какие-то превосходные характеристики.

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

(Заметим также, что если вы не работаете на одном из этих многоядерных ящиков Sun (например, T2000), вам не нужна неизменяемость для безопасности, поскольку один поток достаточно быстр для обработки всех низкоуровневых входных данных.)

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

Другая возможность - создать какой-то шаблон самостоятельно, например

List(classOf[Float],classOf[Int],classOf[String])

и затем написать что-то, что последовательно разбирает этот поток с помощью операторов соответствия:

val FloatClass = classOf[Float]
listEntry match {
  case FloatClass => // Read float
  ...
 }

Такие вещи значительно облегчают работу по чтению двоичных файлов, и это, по крайней мере, как бы функционально, поскольку вы можете отобразить входной поток байтов в список[Any] и затем использовать сопоставление с образцом для извлечения нужных вам данных.

2
ответ дан 14 December 2019 в 04:31
поделиться
Другие вопросы по тегам:

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