# `mmap` — 메모리 맵 파일 지원

메모리 맵 파일 객체는 동시에 `bytearray` 와 파일 객체처럼 작동합니다. `bytearray`를 기대하는 대부분 장소에서 mmap 객체를 사용할 수 있습니다. 예를 들어, `re` 모듈을 사용하여 메모리 맵 파일을 검색할 수 있습니다. `obj[index] = 97`를 사용해서 한 바이트를 변경하거나, 슬라이스에 대입하여 서브 시퀀스를 변경할 수도 있습니다: `obj[i1:i2] = b'...'`. 또한 현재 파일 위치에서 시작하여 데이터를 읽고 쓸 수 있고, 다른 위치로 파일을 `seek()` 할 수 있습니다.

메모리 맵 파일은 `mmap` 생성자로 만드는데, 유닉스와 윈도우에서 다릅니다. 두 경우 모두 갱신을 위해 열린 파일에 대한 파일 기술자를 제공해야 합니다. 기존 파이썬 파일 객체를 매핑하려면, `fileno()` 메서드를 사용하여 fileno 매개 변수에 대한 올바른 값을 가져오십시오. 그렇지 않으면, 파일 기술자를 직접 반환하는 `os.open()` 함수를 사용하여 파일을 열 수 있습니다 (완료되면 파일을 닫아야 합니다).

참고

쓰기 가능하고 버퍼링 되는 파일에 대한 메모리 맵을 만들려면, 먼저 파일을 `flush()`해야 합니다. 버퍼에 대한 지역 변경 사항이 실제로 매핑에 반영되게 하는 데 필요합니다.

유닉스와 윈도우 버전의 생성자 모두에서, access는 선택적 키워드 매개 변수로 지정될 수 있습니다. access는 `ACCESS_READ`, `ACCESS_WRITE` 또는 `ACCESS_COPY` 중 하나의 값을 받아, 읽기 전용, 동시 기록(write-through) 또는 쓸 때 복사(copy-on-write) 메모리를 각각 지정하거나, `ACCESS_DEFAULT`를 사용하여 prot로 위임합니다. access는 유닉스와 윈도우에서 모두 사용할 수 있습니다. access를 지정하지 않으면, 윈도우 mmap은 동시 기록(write-through) 매핑을 반환합니다. 세 가지 액세스 유형 모두에서 초기 메모리값은 지정된 파일에서 가져옵니다. `ACCESS_READ` 메모리 맵에 대입하면 `TypeError` 예외가 발생합니다. `ACCESS_WRITE` 메모리 맵에 대입하면 메모리와 하부 파일에 모두 영향을 줍니다. `ACCESS_COPY` 메모리 맵에 대입하면 메모리에는 영향을 미치지만, 하부 파일은 변경되지 않습니다.

버전 3.7에서 변경: `ACCESS_DEFAULT` 상수가 추가되었습니다.

익명 메모리를 매핑하려면, length와 함께 -1을 fileno로 전달해야 합니다.

class `mmap.``mmap`(fileno, length, tagname=None, access=ACCESS_DEFAULT[, offset])

  (윈도우 버전) 파일 핸들 fileno로 지정된 파일의 length 바이트를 매핑하고, mmap 객체를 만듭니다. length가 파일의 현재 크기보다 크면, 파일은 length 바이트를 포함하도록 확장됩니다. length가 `0` 이면, 맵의 최대 길이는 파일의 현재 길이입니다. 단, 파일이 비어 있으면 윈도우에서 예외가 발생합니다 (윈도우에는 빈 매핑을 만들 수 없습니다).

  tagname가 지정되고 `None`이 아니면, 매핑의 태그 이름을 제공하는 문자열입니다. 윈도우에서는 같은 파일에 대해 여러 가지 다른 매핑을 사용할 수 있게 합니다. 기존 태그의 이름을 지정하면, 해당 태그가 열리고, 그렇지 않으면 이 이름의 새 태그가 만들어집니다. 이 매개 변수가 생략되거나 `None` 이면, 매핑은 이름 없이 만들어집니다. 태그 매개 변수의 사용을 피하면 코드를 유닉스와 윈도우 사이에서 이식성 있게 유지할 수 있습니다.

  offset은 음이 아닌 정수 오프셋으로 지정할 수 있습니다. mmap 참조는 파일 시작 부분으로부터의 오프셋에 상대적입니다. offset의 기본값은 0입니다. offset은 `ALLOCATIONGRANULARITY`의 배수여야 합니다.

  인자 `fileno`, `length`, `access`, `offset`로 감사 이벤트(auditing event) `mmap.__new__`를 발생시킵니다.

class `mmap.``mmap`(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE|PROT_READ, access=ACCESS_DEFAULT[, offset])

  (유닉스 버전) 파일 기술자 fileno로 지정된 파일의 length 바이트를 매핑하고, mmap 객체를 반환합니다. length가 `0` 이면, 맵의 최대 길이는 `mmap`가 호출될 때 파일의 현재 길이입니다.

  flags는 매핑의 특성을 지정합니다. `MAP_PRIVATE`는 비공개 쓸 때 복사 (copy-on-write) 매핑을 생성하므로, mmap 객체의 내용에 대한 변경 사항은 이 프로세스에만 적용되고, `MAP_SHARED`는 파일의 같은 영역을 매핑하는 다른 모든 프로세스와 공유되는 매핑을 만듭니다. 기본값은 `MAP_SHARED`입니다.

  prot가 지정되면 원하는 메모리 보호를 제공합니다; 가장 유용한 두 값은 페이지를 읽거나 쓰도록 지정할 수 있는 `PROT_READ`와 `PROT_WRITE`입니다. prot의 기본값은 `PROT_READ | PROT_WRITE`입니다.

  access는 선택적 키워드 매개 변수로 flags 와 prot 대신 지정 될 수 있습니다. flags, prot 와 access를 모두 지정하는 것은 에러입니다. 이 매개 변수를 사용하는 방법에 대한 정보는 위의 access 설명을 참조하십시오.

  offset은 음이 아닌 정수 오프셋으로 지정할 수 있습니다. mmap 참조는 파일 시작 부분으로부터의 오프셋에 상대적입니다. offset의 기본값은 0입니다. offset은 유닉스 시스템에서 `PAGESIZE`와 같은 `ALLOCATIONGRANULARITY`의 배수여야 합니다.

  To ensure validity of the created memory mapping the file specified by the descriptor fileno is internally automatically synchronized with physical backing store on macOS and OpenVMS.

  이 예제는 `mmap`을 사용하는 간단한 방법을 보여줍니다:

      import mmap

      # write a simple example file
      with open("hello.txt", "wb") as f:
          f.write(b"Hello Python!\n")

      with open("hello.txt", "r+b") as f:
          # memory-map the file, size 0 means whole file
          mm = mmap.mmap(f.fileno(), 0)
          # read content via standard file methods
          print(mm.readline())  # prints b"Hello Python!\n"
          # read content via slice notation
          print(mm[:5])  # prints b"Hello"
          # update content using slice notation;
          # note that new content must have same size
          mm[6:] = b" world!\n"
          # ... and read again using standard file methods
          mm.seek(0)
          print(mm.readline())  # prints b"Hello  world!\n"
          # close the map
          mm.close()

  `mmap`은 `with` 문에서 컨텍스트 관리자로 사용할 수도 있습니다:

      import mmap

      with mmap.mmap(-1, 13) as mm:
          mm.write(b"Hello world!")

  버전 3.2에 추가: 컨텍스트 관리자 지원.

  다음 예제는 익명 맵을 만들고 부모와 자식 프로세스 간에 데이터를 교환하는 방법을 보여줍니다:

      import mmap
      import os

      mm = mmap.mmap(-1, 13)
      mm.write(b"Hello world!")

      pid = os.fork()

      if pid == 0:  # In a child process
          mm.seek(0)
          print(mm.readline())

          mm.close()

  인자 `fileno`, `length`, `access`, `offset`로 감사 이벤트(auditing event) `mmap.__new__`를 발생시킵니다.

  메모리 맵 파일 객체는 다음 메서드를 지원합니다:

  `close`()

    mmap를 닫습니다. 이후에 객체의 다른 메서드를 호출하면 ValueError 예외가 발생합니다. 열려있는 파일을 닫지 않습니다.

  `closed`

    파일이 닫혔으면 `True`입니다.

    버전 3.2에 추가.

  `find`(sub[, start[, end]])

    서브 시퀀스 sub가 발견되는 객체에서 가장 낮은 인덱스를 반환합니다. sub는 [start, end] 범위에 포함되어야 합니다. 선택적 인자 start 와 end는 슬라이스 표기법처럼 해석됩니다. 실패하면 `-1`를 반환합니다.

    버전 3.5에서 변경: 이제 쓰기 가능한 바이트열류 객체를 받아들입니다.

  `flush`([offset[, size]])

    파일의 메모리 내 복사본에 대한 변경 사항을 디스크로 플러시 합니다. 이 호출을 사용하지 않으면, 객체가 파괴되기 전에 변경 내용이 기록된다고 보장할 수 없습니다. offset과 size가 지정되면, 지정된 바이트 범위의 변경 사항만 디스크로 플러시 됩니다; 그렇지 않으면, 매핑의 전체 범위가 플러시 됩니다. offset은 `PAGESIZE` 나 `ALLOCATIONGRANULARITY`의 배수여야 합니다.

    성공을 나타내기 위해 `None`이 반환됩니다. 호출이 실패하면 예외가 발생합니다.

    버전 3.8에서 변경: 이전에는, 성공 시 0이 아닌 값이 반환되었습니다; 윈도우에서 에러 시 0이 반환되었습니다. 성공 시 0 값이 반환되었습니다; 유닉스에서 에러 시 예외가 발생했습니다.

  `madvise`(option[, start[, length]])

    start에서 시작하고 length 바이트만큼 확장하는 메모리 영역에 대해 커널에 조언 option을 보냅니다. option은 시스템에서 사용할 수 있는 MADV_* 상수 중 하나여야 합니다. start와 length가 생략되면, 전체 매핑으로 확장됩니다. 일부 시스템(리눅스 포함)에서, start는 `PAGESIZE`의 배수여야 합니다.

    가용성: `madvise()` 시스템 호출이 있는 시스템.

    버전 3.8에 추가.

  `move`(dest, src, count)

    오프셋 src에서 시작하는 count 바이트를 대상 인덱스 dest로 복사합니다. mmap이 `ACCESS_READ`로 만들어졌으면, move를 호출하면 `TypeError` 예외가 발생합니다.

  `read`([n])

    현재의 파일 위치로부터 최대 n 바이트를 포함하는 `bytes`를 반환합니다. 인자가 생략되거나 `None` 이거나 음수면, 현재 파일 위치에서 매핑의 끝까지 모든 바이트를 반환합니다. 파일 위치는 반환된 바이트의 뒤를 가리키도록 갱신됩니다.

    버전 3.3에서 변경: 인자는 생략되거나 `None` 일 수 있습니다.

  `read_byte`()

    현재 파일 위치의 한 바이트를 정수로 반환하고, 파일 위치를 1 증가시킵니다.

  `readline`()

    현재 파일 위치에서 시작하여 다음 줄 바꿈까지 한 줄을 반환합니다. 반환된 바이트 뒤를 가리키도록 파일 위치가 갱신됩니다.

  `resize`(newsize)

    맵과 하부 파일(있다면)의 크기를 조정합니다. mmap이 `ACCESS_READ` 나 `ACCESS_COPY`로 만들어졌을 때, 맵의 크기를 조정하면 `TypeError` 예외가 발생합니다.

  `rfind`(sub[, start[, end]])

    서브 시퀀스 sub가 발견되는 객체에서 가장 높은 인덱스를 반환합니다. sub는 [start, end] 범위에 포함되어야 합니다. 선택적 인자 start 와 end는 슬라이스 표기법처럼 해석됩니다. 실패하면 `-1`를 반환합니다.

    버전 3.5에서 변경: 이제 쓰기 가능한 바이트열류 객체를 받아들입니다.

  `seek`(pos[, whence])

    파일의 현재 위치를 설정합니다. whence 인자는 선택적이며 기본값은 `os.SEEK_SET` 또는 `0` (절대 파일 위치)입니다; 다른 값은 `os.SEEK_CUR` 또는 `1` (현재 위치를 기준으로 seek)과 `os.SEEK_END` 또는 `2` (파일의 끝을 기준으로 seek)입니다.

  `size`()

    파일의 길이를 반환합니다. 메모리 매핑된 영역의 크기보다 클 수 있습니다.

  `tell`()

    파일 포인터의 현재 위치를 반환합니다.

  `write`(bytes)

    bytes의 바이트를 파일 포인터의 현재 위치에 있는 메모리에 기록하고 기록된 바이트 수를 반환합니다 (쓰기가 실패하면 `ValueError`가 발생하기 때문에 결코 `len(bytes)`보다 작지 않습니다). 파일 위치는 기록된 바이트 뒤를 가리 키도록 갱신됩니다. mmap이 `ACCESS_READ`로 만들어졌으면, 기록할 때 `TypeError` 예외가 발생합니다.

    버전 3.5에서 변경: 이제 쓰기 가능한 바이트열류 객체를 받아들입니다.

    버전 3.6에서 변경: 이제 기록한 바이트 수가 반환됩니다.

  `write_byte`(byte)

    정수 byte를 파일 포인터의 현재 위치에 있는 메모리에 기록합니다; 파일 위치가 `1` 증가합니다. mmap이 `ACCESS_READ`로 만들어졌으면, 기록할 때 `TypeError` 예외가 발생합니다.

## MADV_* 상수

`mmap.``MADV_NORMAL`
`mmap.``MADV_RANDOM`
`mmap.``MADV_SEQUENTIAL`
`mmap.``MADV_WILLNEED`
`mmap.``MADV_DONTNEED`
`mmap.``MADV_REMOVE`
`mmap.``MADV_DONTFORK`
`mmap.``MADV_DOFORK`
`mmap.``MADV_HWPOISON`
`mmap.``MADV_MERGEABLE`
`mmap.``MADV_UNMERGEABLE`
`mmap.``MADV_SOFT_OFFLINE`
`mmap.``MADV_HUGEPAGE`
`mmap.``MADV_NOHUGEPAGE`
`mmap.``MADV_DONTDUMP`
`mmap.``MADV_DODUMP`
`mmap.``MADV_FREE`
`mmap.``MADV_NOSYNC`
`mmap.``MADV_AUTOSYNC`
`mmap.``MADV_NOCORE`
`mmap.``MADV_CORE`
`mmap.``MADV_PROTECT`

  이 옵션은 `mmap.madvise()`로 전달될 수 있습니다. 모든 시스템에서 모든 옵션이 제공되는 것은 아닙니다.

  가용성: madvise() 시스템 호출이 있는 시스템.

  버전 3.8에 추가.