2013-05-11 8 views
5

C'è un modo, utilizzando la libreria Basi SML, per aprire un file in una posizione specifica? Cioè, usa una chiamata al sistema operativo per cambiare la posizione, piuttosto che scansionare il file e buttare via i dati.Ricerca di file con base SML

risposta

7

Questo è difficile. Sfortunatamente, la ricerca non è direttamente supportata. Inoltre, le posizioni dei file sono trasparenti solo per i file binari, cioè quelli che sono stati aperti con la struttura BinIO [1]. Per questa struttura, il tipo corrispondente BinIO.StreamIO.pos è definito come Position.int, che è un tipo intero.

Tuttavia, in un sistema SML che supporta lo stack completo di I/O da quella standard si dovrebbe essere in grado di sintetizzare la seguente funzione cercare utilizzando i più bassi di I/O strati:

(* seekIn : BinIO.instream * Position.int -> unit *) 

fun seekIn(instream, pos) = 
    case BinIO.StreamIO.getReader(BinIO.getInstream instream) of 
     (reader as BinPrimIO.RD{setPos = SOME f, ...}, _) => 
     (f pos; 
      BinIO.setInstream(instream, 
      BinIO.StreamIO.mkInstream(reader, Word8Vector.fromList[])) 
     ) 
    | (BinPrimIO.RD{name, ...}, _) => 
     raise IO.Io{ 
      name = name, 
      function = "seekIn", 
      cause = IO.RandomAccessNotSupported 
     } 

utilizzarlo come:

val file = BinIO.openIn "filename" 
val _ = seekIn(file, 200) 
val bin = BinIO.inputN(file, 1000) 

Se avete bisogno di convertire da Word8Vector a stringa:

val s = Byte.bytesToString bin 

Puoi anche fare l'equivalente per i flussi esterni.

[1] http://standardml.org/Basis/bin-io.html#BIN_IO:SIG:SPEC

+1

Bella risposta! Ma mi chiedevo ... Se sto andando a leggere un file essenzialmente in modo casuale (cercando distanze relativamente lunghe e poi leggendo piccoli pezzi), sto attraversando l'intero stack IO (imperativo/stream/primitivo IO) avanti e indietro davvero ne vale la pena, o forse sarebbe meglio usare semplicemente il 'BinPrimIO.reader' direttamente? – pyon

+1

@ EduardoLeón, non vedo alcun vantaggio particolare nell'utilizzare direttamente l'interfaccia di basso livello. Quello di alto livello è sia più conveniente che più efficiente (buffering e tutto). –

4

Se si riesce a entrare in possesso del reader/writer, allora non dovrebbe avere getPos, setPos e endPos funzioni, a seconda di quale tipo di lettore/scrittore si sta trattando.

Problemi correlati