2013-05-11 40 views
5

有没有一种方法可以使用SML Basis库在特定位置打开文件?也就是说,使用操作系统调用来更改位置,而不是扫描文件并丢弃数据。用SML搜索文件基础

回答

7

这很棘手。不幸的是,寻求并不直接支持。此外,文件位置对于二进制文件而言只是透明的,即用BinIO结构[1]打开的文件位置。对于这种结构,相应的类型BinIO.StreamIO.pos被定义为Position.int,这是一些整数类型。

然而,在支持从标准的完整的I/O堆栈的SML系统,你应该能够合成以下使用较低的I/O层寻求功能:

(* 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 
     } 

这样使用它:

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

如果您需要转换从Word8Vector到字符串:

val s = Byte.bytesToString bin 

您也可以为流出流做同等处理。

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

+1

尼斯的答案!但是我只是想知道......如果我要以一种随机的方式读取一个文件(寻找相对较长的距离然后读取小块),它实际上来回遍历整个IO栈(命令/流/原语IO)值得,或者直接简单地使用'BinPrimIO.reader'会更好一些? – pyon 2013-05-12 01:55:15

+1

@EduardoLeón,我没有看到直接使用底层接口的任何特别优势。高层次更方便,更高效(缓冲和全部)。 – 2013-05-12 07:15:05

4

如果你能设法得到了reader/writer的保持,那么就应该有getPossetPosendPos功能,这取决于哪一种您正在处理的读/写的。