File seeking with SML Basis

北城余情 提交于 2019-12-07 05:38:47

问题


Is there a way, using the SML Basis library, to open a file at a specific position? That is, use an operating system call to change the position, rather than scan through the file and throw away the data.


回答1:


This is tricky. Unfortunately, seeking isn't directly supported. Moreover, file positions are only transparent for binary files, i.e., those that you have opened with the BinIO structure [1]. For this structure, the corresponding type BinIO.StreamIO.pos is defined to be Position.int, which is some integer type.

However, in an SML system that supports the complete I/O stack from the standard you should be able to synthesise the following seek function using the lower I/O layers:

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

Use it like:

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

If you need to convert from Word8Vector to string:

val s = Byte.bytesToString bin

You can do the equivalent for out streams as well.

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




回答2:


If you can manage to get hold of the reader/writer, then they should have getPos, setPos and endPos functions, depending on which kind of reader/writer you are dealing with.



来源:https://stackoverflow.com/questions/16499260/file-seeking-with-sml-basis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!