Functional programming 基于SML的文件查找

Functional programming 基于SML的文件查找,functional-programming,sml,ml,Functional Programming,Sml,Ml,有没有办法使用SML Basis库在特定位置打开文件?也就是说,使用操作系统调用来更改位置,而不是扫描文件并扔掉数据。如果您能够设法获得,则它们应该具有getPos、setPos和endPos功能,这取决于您正在处理的读写器类型。这很棘手。不幸的是,seeking没有得到直接支持。此外,文件位置仅对二进制文件是透明的,即您使用BinIO结构打开的文件[1]。对于此结构,相应的类型BinIO.StreamIO.pos被定义为Position.int,这是一种整数类型 但是,在支持标准完整I/O堆栈

有没有办法使用SML Basis库在特定位置打开文件?也就是说,使用操作系统调用来更改位置,而不是扫描文件并扔掉数据。

如果您能够设法获得,则它们应该具有
getPos
setPos
endPos
功能,这取决于您正在处理的读写器类型。

这很棘手。不幸的是,seeking没有得到直接支持。此外,文件位置仅对二进制文件是透明的,即您使用
BinIO
结构打开的文件[1]。对于此结构,相应的类型
BinIO.StreamIO.pos
被定义为
Position.int
,这是一种整数类型

但是,在支持标准完整I/O堆栈的SML系统中,您应该能够使用较低的I/O层合成以下seek函数:

(* 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
您也可以对out streams执行相同的操作


[1]

回答得好!但我只是想知道。。。如果我基本上是以随机方式读取文件(寻找相对较长的距离,然后读取小块),那么来回遍历整个IO堆栈(命令式/流式/原语IO)真的值得吗,或者直接使用
BinPrimIO.reader
是更好的主意?@EduardoLeón,我不认为直接使用低级接口有什么特别的好处。高级缓存更方便、更高效(缓冲和所有)。