2013-05-11 65 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功能,這取決於哪一種您正在處理的讀/寫的。