Per un'implementazione portatile, si potrebbe desiderare di utilizzare la libreria osicat
, che fornisce un wrapper CFFI per molte chiamate POSIX nel pacchetto osicat-posix
.
C'è un articolo molto bello e breve con il codice per utilizzarlo a http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html (di Nicolas Martyanoff).
di conservare in voi, io per lo cito da lì:
Mappatura di un file è fatto aprendolo con osicat-posix:open
, leggendo la sua dimensione con fstat
, quindi chiamando mmap
. Una volta che il file è stato mappato, possiamo chiudere il descrittore del file, non è più necessario.
(defun mmap-file (path)
(let ((fd (osicat-posix:open path (logior osicat-posix:o-rdonly))))
(unwind-protect
(let* ((size (osicat-posix:stat-size (osicat-posix:fstat fd)))
(addr (osicat-posix:mmap (cffi:null-pointer) size
(logior osicat-posix:prot-read)
(logior osicat-posix:map-private)
fd 0)))
(values addr size))
(osicat-posix:close fd))))
La funzione mmap file restituisce due valori: l'indirizzo della mappatura della memoria e la sua dimensione.
L'eliminazione di questo blocco di memoria viene effettuata con osicat-posix:munmap
.
Aggiungiamo una macro per mappare in modo sicuro e file unmap:
(defmacro with-mmapped-file ((file addr size) &body body)
(let ((original-addr (gensym "ADDR-"))
(original-size (gensym "SIZE-")))
`(multiple-value-bind (,addr ,size)
(mmap-file ,file)
(let ((,original-addr ,addr)
(,original-size ,size))
(unwind-protect
(progn ,@body)
(osicat-posix:munmap ,original-addr ,original-size))))))
Questa macro mmap
s il file data e collega i due dati variabili al suo indirizzo e e dimensione. È quindi possibile calcolare i puntatori di indirizzo con cffi:inc-pointer
e accedere ai contenuti del file con cffi:mem-aref
. Potresti voler costruire i tuoi wrapper attorno a questo per rappresentare il formato del tuo file (per esempio testo normale in UTF-8).
(Rispetto al distacco linkato sopra, ho tolto l'involucro di osicat-posix:munmap
in un'altra funzione della esattamente la stessa firma e l'effetto, perché mi sembrava superfluo per me.)
Grazie per le risposte! Entrambi sembrano risolvere il mio problema, quindi li proverò e accetterò quello che uso. – owagh