用SML Basis搜索文件 [英] File seeking with SML Basis
问题描述
有没有办法使用SML Basis库在特定位置打开文件?也就是说,使用操作系统调用来改变位置,而不是扫描文件并丢弃数据。这很棘手。不幸的是,寻求并不直接支持。此外,文件位置对二进制文件而言只是透明的,即用 BinIO
结构[1]打开的文件位置。对于这个结构,相应的类型 BinIO.StreamIO.pos
被定义为 Position.int
,这是一个整数然而,在支持标准的完整I / O堆栈的SML系统中,您应该能够使用较低的I / O来合成以下查找函数层:
(* seekIn:BinIO.instream * Position.int - >单元*)
有趣的seekIn(instream,pos)=
case
的BinIO.StreamIO.getReader(BinIO.getInstream instream)(读者为BinPrimIO.RD {setPos = SOME f,...},_)= >
(f pos;
BinIO.setInstream(instream,
BinIO.StreamIO.mkInstream(reader,Word8Vector.fromList []))
)
| (BinPrimIO.RD {name,...},_)=>
提高IO.Io {
name = name,
function =seekIn,
cause = IO.RandomAccessNotSupported
}
$ c $
$ b val文件= BinIO.openInfilename
val _ = seekIn(file,200)
val bin = BinIO.inputN(file,1000)
$ b $ p 如果您需要将Word8Vector转换为字符串:
val s = Byte.bytesToString bin
您也可以为out流做同样的处理。
[1] http://standardml.org/Basis /bin-io.html#BIN_IO:SIG:SPEC
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.
解决方案 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
这篇关于用SML Basis搜索文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!