std/memfiles
Исходный кодИзменитьЭтот модуль предоставляет поддержку отображения файлов в память (Posix's mmap) на различных операционных системах.
Он также предоставляет некоторые быстрые итераторы по строкам в текстовых файлах (или других "строкоподобных", переменной длины, разделяемых записях).
Импорты
- winlean, streams, oserrors
Типы
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. ## **Caution**: Platform specific private field.- представляет отображение файла в память Исходный код Изменить
MemMapFileStream = ref MemMapFileStreamObj
- поток, который инкапсулирует
MemFileИсходный код Изменить MemMapFileStreamObj = object of Stream
- Исходный код Изменить
MemSlice = object data*: pointer size*: int
- представляет срез MemFile для итерации по разделяемым строкам/записям Исходный код Изменить
Процедуры
proc `$`(ms: MemSlice): string {.inline, ...raises: [], tags: [], forbids: [].}- Возвращает строку Nim, созданную из MemSlice. Исходный код Изменить
proc `==`(x, y: MemSlice): bool {....raises: [], tags: [], forbids: [].}- Сравнение пары MemSlice на строгое равенство. Исходный код Изменить
proc close(f: var MemFile) {....raises: [OSError], tags: [], forbids: [].}- Закрывает сопоставленный с памятью файл
f. Все изменения записываются обратно в файловую систему, еслиfбыл открыт с правами записи. Исходный код Изменить proc flush(f: var MemFile; attempts: Natural = 3) {....raises: [OSError], tags: [], forbids: [].}- Очищает буфер
fдля количества попыток, равногоattempts. Если возникнут ошибки, будет возбуждено исключениеOSError. Исходный код Изменить proc mapMem(m: var MemFile; mode: FileMode = fmRead; mappedSize = -1; offset = 0; mapFlags = cint(-1)): pointer {. ...raises: [IOError, OSError], tags: [], forbids: [].}-
Возвращает указатель на сопоставленную часть MemFile
m
Исходный код ИзменитьmappedSize-1отображается на весь файл, иoffsetдолжно быть кратно размеру страницы вашей операционной системы proc newMemMapFileStream(filename: string; mode: FileMode = fmRead; fileSize: int = -1): MemMapFileStream {. ...raises: [IOError, OSError], tags: [], forbids: [].}- Создаёт новый поток из файла с именем
filenameс режимомmode. Возбуждает исключение ##OSErrorесли файл не может быть открыт. Список доступных перечислений FileMode см. в модуле system.fileSizeможет быть установлено только в том случае, если файла не существует, и он открыт с правами записи (например, с fmReadWrite). Исходный код Изменить proc open(filename: string; mode: FileMode = fmRead; mappedSize = -1; offset = 0; newFileSize = -1; allowRemap = false; mapFlags = cint(-1)): MemFile {. ...raises: [IOError, OSError], tags: [], forbids: [].}-
Открывает файл, сопоставленный с памятью. Если это не удаётся, возбуждается исключение
OSErrornewFileSizeможет быть установлено только в том случае, если файла не существует, и он открыт с правами записи (например, с 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 resize(f: var MemFile; newFileSize: int) {....raises: [IOError, OSError], tags: [], forbids: [].}- Изменить размер и пересопоставить файл, лежащий в основе
allowRemap MemFile. Если это поддерживается операционной системой/файловой системой, то резервируется место для новых виртуальных страниц. Вызывающая сторона должна достаточно часто ждать завершенияflushдля ограничения использования оперативной памяти для буферизации записи, возможно, непосредственно перед этим вызовом. Примечание: это предполагает, что весь файл сопоставлен для чтения-записи со смещением 0. Также значение.mem, вероятно, изменится. Исходный код Изменить proc unmapMem(f: var MemFile; p: pointer; size: int) {....raises: [OSError], tags: [], forbids: [].}-
Рассопоставляет область памяти
(p, <p+size)сопоставленного файлаf. Все изменения записываются обратно в файловую систему, еслиfбыл открыт с правами записи.
Исходный код Изменитьsizeдолжен быть ровно того размера, который был запрошен черезmapMem.
Итераторы
iterator lines(mfile: MemFile; buf: var string; delim = '\n'; eat = '\r'): string {. inline, ...raises: [], tags: [], forbids: [].}-
Заменяет содержимое переданного буфера каждой новой строкой, как readLine(File).
delim,eat, и логика разделителей точно такая же, как для memSlices, но возвращаются строки Nim.Пример:
var buffer: string = "" for line in lines(memfiles.open("foo"), buffer): echo lineИсходный код Изменить iterator lines(mfile: MemFile; delim = '\n'; eat = '\r'): string {.inline, ...raises: [], tags: [], forbids: [].}-
Возвращает каждую строку в файле в виде строки Nim, как lines(File).
delim,eat, и логика разделителей точно такая же, как для memSlices, но возвращаются строки Nim.Пример:
for line in lines(memfiles.open("foo")): echo lineИсходный код Изменить iterator memSlices(mfile: MemFile; delim = '\n'; eat = '\r'): MemSlice {.inline, ...raises: [], tags: [], forbids: [].}-
Итерируется по [необязательным
eat]delim-разделённым слайсам в MemFilemfile.По умолчанию параметры анализируют строки, заканчивающиеся либо стилем Unix(\l), либо стилем Windows(\r\l), на основе отдельных строк. То есть не каждая строка должна иметь одинаковое окончание. В отличие от readLine(File) и lines(File), устаревшие строки MacOS9 с разделителем \r не поддерживаются как третий вариант для каждой строки. Такие устаревшие файлы MacOS9 могут обрабатываться путём передачи delim='\r', eat='\0', хотя.
Разделители не являются частью возвращаемого слайса. Конечная, не завершенная строка или запись возвращается так же, как и любая другая.
Нестандартные разделители могут быть переданы для итерации по другим типам "подобных строкам" записей переменной длины. Передайте eat='\0', чтобы быть строго
delim-разделённым. (Поглощение необязательного префикса, равного '\0', не поддерживается.)Этот интерфейс с нулевым копированием и ограничением memchr, вероятно, является самым быстрым способом итерирования по записям, похожим на строки, в файле. Однако возвращаемые объекты (данные, размер) не являются строками 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Исходный код Изменить
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/memfiles.html