Spec-Zone.ru › Nim

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: [].}

Открывает файл, сопоставленный с памятью. Если это не удаётся, возбуждается исключение 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 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-разделённым слайсам в MemFile mfile.

По умолчанию параметры анализируют строки, заканчивающиеся либо стилем 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API