2010-06-01 11 views
5

Sto usando Java DataInputStream con scala per analizzare un semplice file binario (che è un pessimo comportamento a causa della mancanza di tipi non firmati, anche in scala, ma questa è una storia diversa) .Approccio di programmazione funzionale per flussi di input/output di Java

Tuttavia, mi trovo costretto a utilizzare una struttura dati mutevole, poiché i flussi di Java sono intrinsecamente entità di conservazione dello stato.

Qual è un buon progetto per racchiudere i flussi di Java con una buona struttura dei dati funzionali?

risposta

5

C'è un progetto attualmente in corso che mira a creare un'IO API per Scala: scala IO Si ispira all'API NIO di Java 7. È ancora un WIP, ma potresti ricavarne alcune idee interessanti. Ci sono anche alcuni esempi su come usarlo, che può essere trovato here

+0

Il punto principale di NIO non è asincrono? Non sono sicuro di voler recuperare dati asincroni. Può rendere le cose semplici più complicate. –

+0

@Elazar 'java.nio' non riguarda solo l'I/O asincrono, ma contiene anche molte funzionalità per le" normali "operazioni sincrone. Il fatto che scala-io sia costruito su 'java.nio' non significa necessariamente che sia solo per l'I/O asincrono. – Jesper

1

Dai un'occhiata allo IO Monad di Haskell per un approccio puramente funzionale.

Un'implementazione pragmatica di Scala implementerebbe un Iterator/Iterable basato sul flusso. Ad esempio scala.io.Source supports questo.

+0

L'implementazione pragmatica di Scala non è adatta, ad esempio, al flusso binario. Cosa succede se desidero leggere un int e poi un breve? L'iteratore non sarà in grado di gestirlo.E anche se potesse mantenere lo stato durante l'utilizzo! –

+0

Ogni implementazione dovrà definire un tipo M [T] come contenitore del flusso. Quindi T deve supportare T.toShort e T.toInt per leggere il valore corrente. Altrimenti M [_] sarebbe un contenitore disomogeneo. –

2

L'intero punto di lettura di un file è quello di ottenere lo stato che non si aveva prima. Pertanto, non capisco esattamente cosa cerchi.

Si può fingere di avere l'intero universo come parametro di input (e output) e creare un analogo "funzionale", ma non ho mai visto una chiara dimostrazione che questo ha caratteristiche superiori.

La maggior parte delle strutture dati funzionali consente di astrarre il numero di copie. Ad esempio, un elenco consente di estendere le operazioni su un singolo elemento a tutti gli elementi in modi convenienti (mappa, riduzione, ecc.). Ma quando vuoi leggere un file, devi astrarre il tipo di dati e inoltre, in realtà non lo vuoi completamente astratto: vuoi abbinare una sorta di modello che ti aspetti. Il modo in cui specifichi questo modello - e cosa fare in condizioni di errore - è, sospetto, il nucleo della tua sfida di lettura di file binari.

(Si noti inoltre che, a meno che non si esegua su uno di questi riquadri Sun altamente multicore (T2000 ad esempio), non è necessaria l'immutabilità per sicurezza poiché un thread è abbastanza veloce da gestire tutto il livello basso elaborazione di input.)

Una possibilità è quella di trattare la lettura di file binari come un problema di analisi. Scala al momento non dispone di una libreria robusta, ma vedi this thread per un bel po 'di codice scritto da Paul Phillips che aiuta in questo senso.

Un'altra possibilità è quella di creare una sorta di modello di te stesso, come

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

e poi scrivere qualcosa che analizza quel flusso sequenziale con istruzioni match:

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

questo tipo di cose rendono il lavoro di leggere i file binari molto più facilmente, ed è almeno una sorta di funzionale, dal momento che è possibile mappare il flusso di byte di input in un List[Any] e quindi utilizzare la corrispondenza del modello per afferrare o ut i dati che vuoi

Problemi correlati