2010-06-01 11 views
5

Estoy usando Java's DataInputStream con scala para analizar un archivo binario simple (que es muy malo exprerience debido a la falta de tipos sin firmar, incluso en scala, pero esa es una historia diferente) .Enfoque de programación funcional para flujos de entrada/salida de Java

Sin embargo, me veo obligado a utilizar una estructura de datos mutable, ya que las transmisiones de Java son entidades inherentemente preservadoras del estado.

¿Qué es un buen diseño para envolver las transmisiones de Java con una buena estructura de datos funcional?

Respuesta

5

Hay un proyecto actualmente en curso que tiene como objetivo crear una API de IO para Scala: scala IO Está inspirado en Java 7 NIO API. Todavía es un WIP, pero puede obtener algunas ideas interesantes de ello. También hay algunos ejemplos sobre cómo usarlo, que se puede encontrar here

+0

¿El principal punto de NIO no es ser asincrónico? No estoy seguro de querer una recuperación asíncrona de datos. Puede hacer que las cosas simples se compliquen más. –

+0

@Elazar 'java.nio' no se trata solo de E/S asincrónicas, también contiene mucha funcionalidad para operaciones síncronas" normales ". El hecho de que scala-io esté basado en 'java.nio' no significa necesariamente que sea solo para E/S asincrónicas. – Jesper

1

Eche un vistazo a IO Monad de Haskell para un enfoque funcional puro.

Una implementación pragmática de Scala implementaría un Iterador/Iterable basado en el flujo. Por ejemplo scala.io.Source supports esto.

+0

La implementación pragmática de Scala no es buena para, por ejemplo, transmisión binaria. ¿Qué sucede si deseo leer un int y luego un short? El iterador no podrá manejar eso.¡Y aunque pudiera mantener el estado mientras lo usaba! –

+0

Cada implementación tendrá que definir un tipo M [T] como un contenedor de su secuencia. Por lo tanto, T debe admitir T.toShort y T.toInt para leer el valor actual. De lo contrario, M [_] sería un contenedor no homogéneo. –

2

El objetivo de leer un archivo es obtener un estado que no tenía antes. Por lo tanto, no entiendo exactamente lo que estás buscando.

Se puede pretender que uno tiene todo el universo como parámetro de entrada (y salida) y crear un análogo "funcional", pero nunca he visto una demostración clara de que tenga características superiores.

La mayoría de las estructuras de datos funcionales le permiten abstraer el número de copia. Por ejemplo, una lista le permite extender operaciones en un elemento individual a todos los elementos de maneras convenientes (mapa, reducir, etc.). Pero cuando quiere leer un archivo, necesita abstraerse sobre el tipo de datos, y además, en realidad no quiere que sea completamente abstracto; desea hacer coincidir algún tipo de plantilla que usted espera. La forma en que especifique esta plantilla, y qué hacer en condiciones de error, es, sospecho, el núcleo de su desafío de lectura de archivos binarios.

(Tenga en cuenta también que a menos que esté ejecutando en uno de esos cuadros Sun multinúcleo (T2000 por ejemplo), no necesita inmutabilidad por seguridad ya que un subproceso es lo suficientemente rápido como para manejar todo el bajo nivel procesamiento de entrada.)

Una posibilidad es tratar la lectura de archivos binarios como un problema de análisis sintáctico. Scala no tiene una biblioteca robusta para eso en este momento, pero vea this thread para obtener un buen código escrito por Paul Phillips que ayuda en este sentido.

Otra posibilidad es crear una especie de plantilla de sí mismo, como

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

y luego escribir algo que descompone el secuencialmente corriente con las declaraciones de los partidos:

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

Este tipo de cosas hacen que el trabajo de leer archivos binarios es mucho más fácil, y es al menos tipo de funcional, ya que puede mapear su flujo de entrada de bytes en un List[Any] y luego usar la coincidencia de patrones para tomar o ut los datos que desea.

Cuestiones relacionadas