Функциональный подход к программированию для потоков ввода / вывода Java - PullRequest
5 голосов
/ 01 июня 2010

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

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

Какой хороший дизайн для обтекания потоков Java хорошей функциональной структурой данных?

Ответы [ 3 ]

5 голосов
/ 01 июня 2010

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

2 голосов
/ 01 июня 2010

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

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

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

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

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

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

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

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

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

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

1 голос
/ 01 июня 2010

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

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

...