memfiles
Этот модуль предоставляет поддержку отображения файлов в памяти (Posix's mmap) на различных операционных системах.
Он также предоставляет некоторые быстрые итераторы по строкам в текстовых файлах (или других "подобных строкам", переменной длины, разделителями записей).
Импорты
- posix, os, streams
Типы
MemFile = object mem*: pointer ## a pointer to the memory mapped file. The pointer ## ## can be used directly to change the contents of the ## ## file, if it was opened with write access. size*: int ## size of the memory mapped file when defined(windows): fHandle*: Handle ## **Caution**: Windows specific public field to allow ## even more low level trickery. mapHandle*: Handle ## **Caution**: Windows specific public field. wasOpened*: bool ## **Caution**: Windows specific public field. else: handle*: cint ## **Caution**: Posix specific public field. flags: cint ## **Caution**: Platform specific private field.- представляет собой файл, отображенный в памяти Исходный код Редактировать
MemSlice = object data*: pointer size*: int
- представляет собой срез MemFile для итерации по разделительным строкам/записям Исходный код Редактировать
MemMapFileStream = ref MemMapFileStreamObj
- поток, инкапсулирующий
MemFileИсходный код Редактировать MemMapFileStreamObj = object of Stream mf: MemFile mode: FileMode pos: ByteAddress
- Исходный код Редактировать
Процедуры
proc mapMem(m: var MemFile; mode: FileMode = fmRead; mappedSize = -1; offset = 0; mapFlags = cint(-1)): pointer {...}{. raises: [IOError, OSError], tags: [].}-
возвращает указатель на отображенный фрагмент MemFile
m
Исходный код РедактироватьmappedSizeотображения-1на весь файл, аoffsetдолжны быть кратны размеру страницы вашей ОС proc unmapMem(f: var MemFile; p: pointer; size: int) {...}{.raises: [OSError], tags: [].}-
разобрасывает область памяти
(p, <p+size)отображенного файлаf. Все изменения записываются обратно в файловую систему, еслиfбыл открыт для записи.
Исходный код Редактироватьsizeдолжен быть ровно того размера, который был запрошен посредствомmapMem. proc open(filename: string; mode: FileMode = fmRead; mappedSize = -1; offset = 0; newFileSize = -1; allowRemap = false; mapFlags = cint(-1)): MemFile {...}{. raises: [IOError, OSError], tags: [].}-
открывает файл, отображенный в памяти. Если это не удается, возникает
OSError.newFileSizeможет быть установлено только в том случае, если файл не существует и открыт для записи (например, с fmReadWrite).mappedSizeиoffsetмогут быть использованы для отображения только фрагмента файла.offsetдолжны быть кратны размеру страницы вашей ОС (обычно 4К или 8К, но уникально для вашей ОС)allowRemapтребуется только в том случае, если вы хотите вызватьmapMemна результирующем MemFile; в противном случае дескрипторы файлов не будут оставаться открытыми.mapFlagsпозволяет вызывающим сторонам переопределять стандартные значения для флагов отображения памяти с помощью битового маскирования различных, вероятно, специфичных для платформы флагов, которые могут быть проигнорированы или даже привести к тому, чтоopenпотерпит неудачу, если указаны неверно.Пример:
var mm, mm_full, mm_half: MemFile mm = memfiles.open("/tmp/test.mmap", mode = fmWrite, newFileSize = 1024) # Create a new file mm.close() # Read the whole file, would fail if newFileSize was set mm_full = memfiles.open("/tmp/test.mmap", mode = fmReadWrite, mappedSize = -1) # Read the first 512 bytes mm_half = memfiles.open("/tmp/test.mmap", mode = fmReadWrite, mappedSize = 512)Исходный код Редактировать proc flush(f: var MemFile; attempts: Natural = 3) {...}{.raises: [OSError], tags: [].}- Очищает буфер
fдля количества попыток, равныхattempts. Если возникнут ошибки, будет возбуждено исключениеOSError. Исходный код Редактировать proc resize(f: var MemFile; newFileSize: int) {...}{.raises: [IOError, OSError], tags: [].}- изменить размер и повторно отобразить файл, лежащий в основе
allowRemap MemFile. Примечание: предполагается, что весь файл отображен в режиме чтения-записи по смещению ноль. Кроме того, значение.mem, вероятно, изменится. Примечание: Это пока не доступно в Windows. Исходный код Редактировать proc close(f: var MemFile) {...}{.raises: [OSError], tags: [].}- закрывает отображенный в памяти файл
f. Все изменения записываются обратно в файловую систему, еслиfбыл открыт для записи. Исходный код Редактировать proc `==`(x, y: MemSlice): bool {...}{.raises: [], tags: [].}- Сравнение пары MemSlice на точное равенство. Исходный код Редактировать
proc `$`(ms: MemSlice): string {...}{.inline, raises: [], tags: [].}- Возвращает строку Nim, построенную из MemSlice. Исходный код Редактировать
proc newMemMapFileStream(filename: string; mode: FileMode = fmRead; fileSize: int = -1): MemMapFileStream {...}{. raises: [IOError, OSError], tags: [].}- создаёт новый поток из файла с именем
filenameв режимеmode. Возбуждает исключение ##OSErrorесли файл не может быть открыт. См. модуль system для списка доступных перечислений FileMode.fileSizeможет быть установлено только в том случае, если файл не существует и открыт для записи (например, с fmReadWrite). Исходный код Редактировать
Итераторы
iterator memSlices(mfile: MemFile; delim = '\n'; eat = '\c'): MemSlice {...}{.inline, raises: [], tags: [].}-
Итерация по [необязательным
eat]delim-разделительным срезам в MemFilemfile.По умолчанию параметры анализируют строки, заканчивающиеся стилем Unix(\l) или Windows(\r\l), по строкам. То есть не каждая строка должна заканчиваться одинаково. В отличие от readLine(File) & lines(File), устаревшие строки MacOS9 \r не поддерживаются в качестве третьего варианта для каждой строки. Такие устаревшие файлы MacOS9 можно обработать, передав delim='\r', eat='\0', хотя.
Разделители не являются частью возвращаемого среза. Конечная не завершённая строка или запись возвращается как любая другая.
Нестандартные разделители могут быть переданы для итерации по другим видам "строкоподобных" записей переменной длины. Передайте eat='\0', чтобы строго
delim-разделять. (Поглощение необязательного префикса, равного '\0', не поддерживается.)Этот интерфейс без копирования, ограниченный memchr, вероятно, является самым быстрым способом итерирования по строкоподобным записям в файле. Однако возвращаемые объекты (data, size) не являются строками Nim, ограниченными границами массивами Nim или даже завершёнными строками C. Поэтому требуется осторожность при доступе к данным (например, думайте о функциях C mem*, а не str*).
Пример:
var count = 0 for slice in memSlices(memfiles.open("foo")): if slice.size > 0 and cast[cstring](slice.data)[0] != '#': inc(count) echo countИсходный код Редактировать iterator lines(mfile: MemFile; buf: var TaintedString; delim = '\n'; eat = '\c'): TaintedString {...}{. inline, raises: [], tags: [].}-
Заменяет содержимое переданного буфера каждой новой строкой, как readLine(File).
delim,eat, и логика разделителей точно такие же, как у memSlices, но возвращаются строки Nim.Пример:
var buffer: TaintedString = "" for line in lines(memfiles.open("foo"), buffer): echo lineИсходный код Редактировать iterator lines(mfile: MemFile; delim = '\n'; eat = '\c'): TaintedString {...}{. inline, raises: [], tags: [].}-
Возвращает каждую строку в файле в виде строки Nim, как lines(File).
delim,eat, и логика разделителей точно такие же, как у memSlices, но возвращаются строки Nim.Пример:
for line in lines(memfiles.open("foo")): echo lineИсходный код Редактировать
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/memfiles.html