Spec-Zone.ru › Nim 1

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-разделительным срезам в MemFile mfile.

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

Spec-Zone.ru

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