파일 시스템
파일 시스템 (Filesystem)
파일과 디렉토리를 다루는 Racket의 파일 시스템 API를 설명하는 문서예요. 표준 경로 찾기, 파일/디렉토리 생성·삭제·이름변경, 파일 시스템 변경 감지, 실행 시점에 필요한 경로 선언, 그리고 그 밖의 파일·디렉토리 유틸리티까지 폭넓게 다룹니다.
출처: Racket Reference
본문
경로 찾기 (Locating Paths)
procedure
(find-system-path kind) → path?
kind : symbol?
kind가 지정하는 표준 종류의 경로에 해당하는, 기계별로 특화된 경로를 반환해요. kind는 다음 중 하나여야 합니다.
-
'home-dir— 현재 사용자의 홈 디렉토리입니다.- 모든 플랫폼에서
PLTUSERHOME환경 변수가 완전한 경로(complete path)로 정의되어 있다면 그 경로를 사용자의 홈 디렉토리로 사용합니다. - Unix와 Mac OS에서,
PLTUSERHOME이 적용되지 않을 때는"~"경로를 확장해 사용자의 홈 디렉토리를 알아냅니다. 확장은 먼저HOME환경 변수를 확인하는 방식으로 이루어집니다. 아무것도 정의되어 있지 않다면USER와LOGNAME환경 변수를 (그 순서대로) 참고해 사용자 이름을 찾고, 그다음 시스템 파일을 참고해 사용자 홈 디렉토리를 알아냅니다. - Windows에서,
PLTUSERHOME이 적용되지 않을 때는 Windows 레지스트리로 결정되는 사용자별 프로필 디렉토리를 사용합니다. 레지스트리가 어떤 이유로 디렉토리를 제공하지 못하면, 존재하는 디렉토리를 가리키는 한USERPROFILE환경 변수의 값을 대신 사용합니다.USERPROFILE도 실패하면HOMEDRIVE와HOMEPATH환경 변수가 지정하는 디렉토리를 사용합니다. 그 환경 변수들도 정의되지 않았거나 가리키는 디렉토리가 여전히 존재하지 않으면, 현재 실행 파일이 들어 있는 디렉토리를 홈 디렉토리로 사용합니다.
- 모든 플랫폼에서
-
'pref-dir— 현재 사용자의 환경설정(preferences)을 저장하는 표준 디렉토리입니다. 환경설정 디렉토리는 존재하지 않을 수도 있습니다.- Unix에서 환경설정 디렉토리는 보통
XDG_CONFIG_HOME이 지정하는 경로의"racket"하위 디렉토리이며,XDG_CONFIG_HOME이 절대 경로로 설정되지 않았거나PLTUSERHOME이 설정되어 있으면 사용자 홈 디렉토리의".config/racket"입니다. 어느 쪽이든 그 디렉토리가 존재하지 않지만 사용자 홈 디렉토리에".racket"디렉토리가 존재한다면, 그 디렉토리가 환경설정 디렉토리가 됩니다. - Windows에서 환경설정 디렉토리는
PLTUSERHOME으로 결정되었을 때는 사용자 홈 디렉토리의"Racket"이고, 그 외에는 Windows 레지스트리가 지정하는 사용자 애플리케이션-데이터 폴더 안에 있으며, 그 폴더는 보통 사용자 프로필 디렉토리의"Application Data"입니다. - Mac OS에서 환경설정 디렉토리는 사용자 홈 디렉토리의
"Library/Preferences"입니다.
- Unix에서 환경설정 디렉토리는 보통
-
'pref-file— 환경설정 값들의, 심볼을 키로 하는 연관 리스트(association list)를 담는 파일입니다. 파일의 디렉토리 경로는 항상'pref-dir에 대해 반환된 결과와 일치합니다. 파일 이름은 Unix와 Windows에서는"racket-prefs.rktd"이고, Mac OS에서는"org.racket-lang.prefs.rktd"입니다. 파일의 디렉토리는 존재하지 않을 수도 있습니다.get-preference도 함께 보세요. -
'temp-dir— 임시 파일을 저장하는 표준 디렉토리입니다. Unix와 Mac OS에서 이는TMPDIR환경 변수가 정의되어 있으면 그것이 지정하는 디렉토리이고, 그 외에는"/var/tmp","/usr/tmp","/tmp"중 처음으로 존재하는 경로입니다. Windows에서는TMP또는TEMP환경 변수가 정의되어 있으면 그것이 지정하는 디렉토리이고, 그 외에는 현재 디렉토리입니다. -
'init-dir— Racket 실행 파일이 사용하는 초기화 파일(initialization file)이 들어 있는 디렉토리입니다.- Unix에서 초기화 디렉토리는
'pref-dir에 대해 반환된 결과와 같습니다. 단, 그 디렉토리가 존재하지 않고 사용자 홈 디렉토리에".racketrc"파일이 존재한다면 홈 디렉토리가 초기화 디렉토리가 됩니다. - Windows에서 초기화 디렉토리는 사용자 홈 디렉토리와 같습니다.
- Mac OS에서 초기화 디렉토리는 사용자 홈 디렉토리의
"Library/Racket"입니다. 단, 그곳에"racketrc.rktl"이 없고 홈 디렉토리에".racketrc"파일이 존재한다면 홈 디렉토리가 초기화 디렉토리가 됩니다.
- Unix에서 초기화 디렉토리는
-
'init-file— Racket 실행 파일이 시작할 때 로드하는 파일입니다. 경로의 디렉토리 부분은'init-dir에 대해 반환된 경로와 같습니다.- Windows에서 파일 이름 부분은
"racketrc.rktl"입니다. - Unix와 Mac OS에서 파일 이름 부분은
"racketrc.rktl"입니다. 단,'init-dir에 대해 반환된 경로가 사용자 홈 디렉토리라면 파일 이름 부분은".racketrc"입니다.
- Windows에서 파일 이름 부분은
-
'config-dir— 설치(installation)의 설정을 위한 디렉토리입니다. 이 디렉토리는PLTCONFIGDIR환경 변수가 지정하며,--config또는-G명령줄 플래그로 덮어쓸 수 있습니다. 환경 변수나 플래그가 지정되지 않았거나 그 값이 유효한 경로 이름이 아니면, 이 디렉토리는 현재 실행 파일에 상대적인"etc"디렉토리로 기본 설정됩니다.(find-system-path 'config-dir)의 결과가 상대 경로라면 그것은 현재 실행 파일에 상대적입니다. 디렉토리는 존재하지 않을 수도 있습니다. -
'host-config-dir—'config-dir와 같지만, 크로스 플랫폼 빌드 모드(racket에 대한-C또는--cross인자로 선택됨; Command Line 참고)가 선택되었을 때 그 결과는 대상 시스템이 아니라 현재 시스템의 설치를 위한 디렉토리를 가리킵니다. -
'addon-dir— 사용자별 Racket 설정, 패키지, 확장을 위한 디렉토리입니다. 이 디렉토리는PLTADDONDIR환경 변수가 지정하며,--addon또는-A명령줄 플래그로 덮어쓸 수 있습니다. 환경 변수나 플래그가 지정되지 않았거나 그 값이 유효한 경로 이름이 아니면, 이 디렉토리는 플랫폼별 위치로 기본 설정됩니다. 디렉토리는 존재하지 않을 수도 있습니다.- Unix에서 기본값은 보통
XDG_DATA_HOME이 지정하는 경로의"racket"하위 디렉토리이며,XDG_CONFIG_HOME이 절대 경로로 설정되지 않았거나PLTUSERHOME이 설정되어 있으면 사용자 홈 디렉토리의".local/share/racket"입니다. 그 디렉토리가 존재하지 않지만 사용자 홈 디렉토리에".racket"디렉토리가 존재한다면, 그".racket"디렉토리 경로가 대신 기본값입니다. - Windows에서 기본값은
'pref-dir디렉토리와 같습니다. - Mac OS에서 기본값은 사용자 홈 디렉토리 안의
"Library/Racket"입니다.
- Unix에서 기본값은 보통
-
'host-addon-dir—'addon-dir와 같지만, 크로스 플랫폼 빌드 모드(racket에 대한-C또는--cross인자로 선택됨; Command Line 참고)가 선택되었을 때 그 결과는 대상 시스템이 아니라 현재 시스템의 설치를 위한 디렉토리를 가리킵니다.- base 패키지 버전 8.17.0.2에서 추가됨.
-
'cache-dir— 사용자별 캐시를 저장하는 디렉토리입니다. 디렉토리는 존재하지 않을 수도 있습니다.- Unix에서 캐시 디렉토리는 보통
XDG_CACHE_HOME이 지정하는 경로의"racket"하위 디렉토리이며,XDG_CACHE_HOME이 절대 경로로 설정되지 않았거나PLTUSERHOME이 설정되어 있으면 사용자 홈 디렉토리의".cache/racket"입니다. 그 디렉토리가 존재하지 않지만 홈 디렉토리에".racket"디렉토리가 존재한다면, 그".racket"디렉토리가 대신 캐시 디렉토리입니다. - Windows에서 캐시 디렉토리는
'addon-dir에 대해 반환된 결과와 같습니다. - Mac OS에서 캐시 디렉토리는 사용자 홈 디렉토리 안의
"Library/Caches/Racket"입니다.
- Unix에서 캐시 디렉토리는 보통
-
'doc-dir— 현재 사용자의 문서를 저장하는 표준 디렉토리입니다. Unix에서는 사용자 홈 디렉토리입니다. Windows에서는PLTUSERHOME으로 결정되었을 때는 사용자 홈 디렉토리이고, 그 외에는 Windows 레지스트리가 지정하는 사용자 문서 폴더이며, 보통 사용자 홈 디렉토리의"My Documents"입니다. Mac OS에서는 사용자 홈 디렉토리의"Documents"디렉토리입니다. -
'desk-dir— 현재 사용자의 바탕화면 디렉토리입니다. Unix에서는 사용자 홈 디렉토리입니다. Windows에서는PLTUSERHOME으로 결정되었을 때는 사용자 홈 디렉토리이고, 그 외에는 Windows 레지스트리가 지정하는 사용자 바탕화면 폴더이며, 보통 사용자 홈 디렉토리의"Desktop"입니다. Mac OS에서는 사용자 홈 디렉토리의"Desktop"입니다. -
'sys-dir— Windows 운영체제가 들어 있는 디렉토리입니다. Unix와 Mac OS에서는 결과가"/"입니다. -
'exec-file— 현재 호출에 대해 운영체제가 제공하는 Racket 실행 파일의 경로입니다. 일부 운영체제에서는 이 경로가 상대적일 수 있습니다.- GRacket의 경우 실행 파일 경로는 GRacket 실행 파일의 이름입니다.
-
'run-file— 현재 실행 파일의 경로입니다. 이는'exec-file의 결과와 다를 수 있는데, 그 이유는 Racket(또는 GRacket) 실행 파일에--name또는-N명령줄 플래그를 통해 대체 경로가 제공되었거나, 임베딩 실행 파일이 대체 경로를 설치했기 때문입니다. 특히make-racket-launcher가 만든 "launcher" 스크립트는 이 경로를 스크립트의 경로로 설정합니다. -
'collects-dir— 라이브러리의 주 컬렉션(collection) 경로입니다 (Libraries and Collections 참고). 이 경로가 상대적이라면(find-system-path 'exec-file)이 보고하는 실행 파일에 상대적입니다. 다만 후자는 소프트 링크이거나 사용자의 실행 파일 검색 경로에 상대적일 수 있으므로, 두 결과는find-executable-path로 결합해야 합니다.'collects-dir경로는 보통 Racket 실행 파일에 내장되지만,--collects또는-X명령줄 플래그로 덮어쓸 수 있습니다. -
'host-collects-dir—'collects-dir와 같지만, 크로스 플랫폼 빌드 모드(racket에 대한-C또는--cross인자로 선택됨; Command Line 참고)가 선택되었을 때 그 결과는 대상 시스템이 아니라 현재 시스템의 설치를 위한 디렉토리를 가리킵니다. 크로스 플랫폼 빌드 모드에서 컬렉션 파일은 보통 대상 시스템의 설치에서 읽히지만, 일부 작업은 (외부 라이브러리를 담는 디렉토리처럼) 주 라이브러리-컬렉션 경로에 상대적으로 설정된 현재-시스템 디렉토리를 필요로 합니다. -
'orig-dir— 시작 시점의 현재 디렉토리입니다.(find-system-path 'exec-file)이나(find-system-path 'run-file)의 상대 경로 결과를 완전한 경로로 변환할 때 유용합니다.
base 패키지 버전 6.0.0.3에서 변경됨: PLTUSERHOME 추가. 버전 6.9.0.1에서 변경됨: 'host-config-dir와 'host-collects-dir 추가. 버전 7.8.0.9에서 변경됨: 'cache-dir 추가, 그리고 이전 경로를 폴백으로 두고 Unix에서 XDG 디렉토리를 선호하도록 변경, Mac OS에도 유사한 조정 적용.
procedure
(path-list-string->path-list str default-path-list)
→ (listof (or/c path? 'same))
str : (or/c string? bytes?)
default-path-list : (listof (or/c path? 'same))
경로 리스트를 담은 문자열 또는 바이트 문자열을 파싱해 경로 리스트를 반환해요. Unix와 Mac OS에서 경로-리스트 문자열 안의 경로는 :로 구분됩니다. Windows에서는 ;로 구분되며 문자열 안의 모든 "는 버려집니다. 경로 리스트가 빈 경로를 포함할 때마다 default-path-list 리스트가 반환된 경로 리스트에 삽입(splice)됩니다. 유효한 경로를 형성하지 못하는 str의 부분은 반환된 리스트에 포함되지 않습니다. 주어진 str은 nul 문자나 nul 바이트를 포함해서는 안 됩니다.
base 패키지 버전 8.0.0.10에서 변경됨: default-path-list에서 'same을 허용하도록 변경.
procedure
(find-executable-path program [related deepest?])
→ (or/c path? #f)
program : path-string?
related : (or/c path-string? #f) = #f
deepest? : any/c = #f
실행 파일 program의 경로를 찾아 반환하며, 경로를 찾지 못하면 #f를 반환해요.
Windows에서 program을 찾지 못했고 program에 파일 확장자가 없으면 program에 ".exe"를 붙여 검색을 다시 시작하며, ".exe"가 붙은 경로도 찾지 못했을 때만 결과가 #f입니다. 확장자가 붙은 program만 찾은 경우 결과에는 .exe 확장자가 포함됩니다.
related가 #f가 아니면 그것은 상대 경로 문자열이어야 하며, program에 대해 찾은 경로는 related 파일이나 디렉토리가 실행 파일과 같은 디렉토리에 존재하도록 하는 경로여야 합니다. 그러면 결과는 실행 파일의 경로 대신 찾은 related의 전체 경로입니다.
이 프로시저는 Racket 실행 파일이 표준 라이브러리 컬렉션 디렉토리를 찾는 데 사용합니다 (Libraries and Collections 참고). 이 경우 program은 Racket을 시작하는 데 쓰인 이름이고 related는 "collects"입니다. related 인자가 사용되는 이유는, Unix와 Mac OS에서 program이 일련의 소프트 링크를 포함할 수 있고 이 경우 related가 체인에서 어느 링크가 관련 있는지를 결정하기 때문입니다.
related가 #f가 아닐 때 find-executable-path가 다른 파일 경로로의 링크인 program을 찾지 못하면, 검색은 링크의 대상(destination)으로 계속될 수 있습니다. related를 찾거나 링크 체인의 끝에 도달할 때까지 추가 링크를 검사합니다. deepest?가 #f(기본값)이면 결과는 related가 발견된 링크 체인에서의 첫 번째 경로에 해당합니다(그리고 추가 링크는 실제로 탐색되지 않습니다). 그 외에는 결과는 related가 발견된 체인의 마지막 링크에 해당합니다.
program이 경로 없는 이름이라면 find-executable-path는 PATH 환경 변수의 값을 가져옵니다. 이 환경 변수가 정의되어 있으면 find-executable-path는 위에서 설명한 경로 포함 program에 대한 검색 알고리즘을 사용해 PATH의 각 경로를 program의 접두사로 시도합니다. PATH 환경 변수가 정의되어 있지 않으면 program에 현재 디렉토리를 접두사로 붙여 위의 검색 알고리즘을 사용합니다. (Windows에서는 현재 디렉토리가 항상 암묵적으로 PATH의 첫 번째 항목이므로, find-executable-path는 Windows에서 현재 디렉토리를 먼저 확인합니다.)
base 패키지 버전 8.1.0.7에서 변경됨: Windows에서 ".exe"로 검색 추가.
파일 (Files)
procedure
(file-exists? path) → boolean?
path : path-string?
파일(디렉토리가 아닌) 경로가 존재하면 #t를, 그렇지 않으면 #f를 반환해요.
Windows에서 file-exists?는 특수 파일 이름의 모든 변형(예: "LPT1", "x:/baddir/LPT1")에 대해 #t를 보고합니다.
procedure
(link-exists? path) → boolean?
path : path-string?
링크 경로가 존재하면 #t를, 그렇지 않으면 #f를 반환해요.
술어(predicate) file-exists?나 directory-exists?는 링크 또는 링크 연쇄의 최종 대상에서 동작하는 반면, link-exists?는 path의 기본 부분(경로에서 마지막 이름을 제외한 전부)을 해석하기 위해 링크만 따라갑니다.
이 프로시저는 exn:fail:filesystem 예외를 절대 던지지 않습니다.
Windows에서 link-exists?는 심볼릭 링크와 junction 둘 다에 대해 #t를 보고합니다.
base 패키지 버전 6.0.1.12에서 변경됨: Windows에서 링크 지원 추가.
procedure
(file-or-directory-type path [must-exist?])
→ (or/c 'file 'directory 'link 'directory-link #f)
path : path-string?
must-exist? : any/c = #f
path에 접근할 수 있다고 가정할 때, path가 파일, 디렉토리, 링크, 또는 (Windows의 경우) 디렉토리 링크를 가리키는지 보고해요. (make-file-or-directory-link도 함께 보세요.)
path에 접근할 수 없으면, must-exist?가 #f일 때 결과는 #f이고, 그 외에는 exn:fail:filesystem 예외가 던져집니다.
base 패키지 버전 7.8.0.5에서 추가됨.
procedure
(delete-file path) → void?
path : path-string?
path라는 파일이 존재하면 삭제하고, 그렇지 않으면 exn:fail:filesystem 예외를 던져요. path가 링크라면 링크의 대상이 아니라 링크 자체가 삭제됩니다.
Windows에서 파일 삭제의 초기 시도가 권한 오류로 실패하고 current-force-delete-permissions의 값이 참이면, delete-file은 파일의 권한을 (쓰기가 허용되도록) 바꾼 뒤 파일을 삭제하려 합니다. 권한 변경 후 삭제는 비원자적(non-atomic) 시퀀스이며, 삭제가 실패해도 권한 변경을 되돌리려는 시도는 없습니다.
Windows에서 delete-file은 심볼릭 링크를 삭제할 수 있지만 junction은 삭제할 수 없습니다. junction을 삭제하려면 delete-directory를 사용하세요.
Windows에서, 어떤 프로세스(예: 백그라운드 검색 인덱서)가 파일을 사용하는 동안 파일이 삭제되면 파일의 내용은 결국 사라지지만, 파일이 더 이상 사용되지 않을 때까지 파일 이름은 점유된 채로 남는다는 점에 주의하세요. 이름이 점유되어 있는 동안 파일을 열거나, 삭제하거나, 교체하려는 시도는 (file-exists 오류가 아니라) 권한 오류를 일으킵니다. 이런 함정을 피하려면 파일을 삭제하기 전에 생성된 임시 이름으로 옮기는 것이 일반적인 기법입니다. delete-directory/files도 함께 보세요.
base 패키지 버전 6.1.1.7에서 변경됨: Windows 동작이 current-force-delete-permissions를 사용하도록 변경.
procedure
(rename-file-or-directory old new [exists-ok?]) → void?
old : path-string?
new : path-string?
exists-ok? : any/c = #f
old라는(존재한다면) 파일 또는 디렉토리의 이름을 new로 바꿔요. 파일 또는 디렉토리가 성공적으로 이름이 바뀌지 않으면 exn:fail:filesystem 예외가 던져집니다.
이 프로시저는 (같은 파일 시스템 상에서) 파일/디렉토리를 다른 디렉토리로 옮기는 데도, 디렉토리 안에서 파일/디렉토리 이름을 바꾸는 데도 사용할 수 있어요. exists-ok?가 참 값으로 제공되지 않는 한 new는 기존 파일이나 디렉토리를 가리킬 수 없지만, 그 검사는 Unix와 Mac OS에서 이름 바꾸기 연산과 원자적이지 않습니다. exists-ok?가 참이더라도, old가 디렉토리일 때 new는 기존 파일을 가리킬 수 없으며 그 반대도 마찬가지입니다.
new가 존재하고 교체된다면 그 교체는 Unix와 Mac OS에서 원자적이지만, Windows에서는 원자적임이 보장되지 않습니다. 게다가 new가 존재하고 어떤 프로세스에 의해 읽기나 쓰기로 열려 있다면, Windows에서 그것을 교체하려는 시도는 대개 실패합니다. call-with-atomic-output-file도 함께 보세요.
old가 링크라면 링크의 대상이 아니라 링크 자체의 이름이 바뀌며, 기존 new를 교체하는 데 있어서는 파일로 간주됩니다.
Windows에서, 디렉토리 안의 어떤 파일이 열려 있으면 그 디렉토리의 이름은 바꿀 수 없다는 점에 주의하세요. 이 제약은 (기본 Windows 설정처럼) 검색 인덱서가 백그라운드에서 실행 중일 때 특히 문제가 됩니다. 가능한 해결책은 copy-directory/files와 delete-directory/files를 결합하는 것인데, 후자는 열려 있는 파일도 처리할 수 있지만 그 시퀀스는 분명히 원자적이지 않고 일시적으로 파일을 복제합니다.
procedure
(file-or-directory-modify-seconds path [secs-n]) → exact-integer?
path : path-string?
secs-n : #f = #f
(file-or-directory-modify-seconds path secs-n) → void?
path : path-string?
secs-n : exact-integer?
(file-or-directory-modify-seconds path [secs-n fail-thunk]) → any
path : path-string?
secs-n : (or/c exact-integer? #f) = #f
fail-thunk : (-> any) = (lambda () (raise (make-exn:fail:filesystem ....)))
secs-n이 제공되지 않거나 #f일 때, 파일 또는 디렉토리의 마지막 수정 날짜를 epoch 이후의 초 단위로 반환해요 (Time도 함께 보세요).
Windows의 FAT 파일 시스템에서는 디렉토리에 수정 날짜가 없습니다. 따라서 디렉토리에 대해서는 생성 날짜가 반환되고 파일에 대해서는 수정 날짜가 반환됩니다.
secs-n이 제공되고 #f가 아니면, path의 접근 시간과 수정 시간이 주어진 시간으로 설정됩니다.
오류 시(예: 그런 파일이 없을 때) fail-thunk가 (꼬리 호출을 통해) 호출되어 file-or-directory-modify-seconds 호출의 결과를 만들어냅니다. fail-thunk가 제공되지 않으면 오류는 exn:fail:filesystem을 던집니다.
procedure
(file-or-directory-permissions path [mode])
→ (listof (or/c 'read 'write 'execute))
path : path-string?
mode : #f = #f
(file-or-directory-permissions path mode) → (integer-in 0 65535)
path : path-string?
mode : 'bits
(file-or-directory-permissions path mode) → void
path : path-string?
mode : (integer-in 0 65535)
인자를 하나만 주거나 두 번째 인자로 #f를 주면, 현재 사용자와 그룹이 주어진 파일 또는 디렉토리 경로에 대해 가지는 권한을 나타내는 'read, 'write, 'execute를 담은 리스트를 반환해요. Unix와 Mac OS에서 권한은 실제 사용자(real user)가 아니라 현재 유효 사용자(current effective user)에 대해 검사됩니다.
두 번째 인자로 'bits가 주어지면, 결과는 파일 또는 디렉토리의 속성(주로 권한)을 플랫폼별로 인코딩한 정수이며, 현재 사용자와 그룹과 무관합니다. 인코딩의 가장 낮은 9비트는 어느 정도 이식 가능하며, 파일 또는 디렉토리의 소유자, 그룹 구성원, 또는 다른 사용자에 대한 권한을 반영합니다:
#o400: 소유자에게 읽기 권한 있음#o200: 소유자에게 쓰기 권한 있음#o100: 소유자에게 실행 권한 있음#o040: 그룹에게 읽기 권한 있음#o020: 그룹에게 쓰기 권한 있음#o010: 그룹에게 실행 권한 있음#o004: 다른 사용자에게 읽기 권한 있음#o002: 다른 사용자에게 쓰기 권한 있음#o001: 다른 사용자에게 실행 권한 있음
user-read-bit 등도 함께 보세요. Windows에서 세 범주(소유자, 그룹, 기타)의 권한은 항상 같으며, 읽기와 실행 권한은 항상 사용 가능합니다. Unix와 Mac OS에서 더 높은 비트는 플랫폼별 의미를 가집니다.
두 번째 인자로 정수가 주어지면, 그것은 파일에 설치할 (주로 권한인) 속성의 인코딩으로 사용됩니다.
모든 모드에서 오류 시(예: 그런 파일이 없을 때) exn:fail:filesystem 예외가 던져집니다.
procedure
(file-or-directory-stat path [as-link?])
→ (and/c (hash/c symbol? any/c) hash-eq?)
path : path-string?
as-link? : boolean? = #f
다음 키와 값을 가진 해시를 반환하며, 각 값은 현재 음이 아닌 정확한 정수입니다:
'device-id: 장치 ID'inode: inode 번호'mode: 모드 비트 (아래 참고)'hardlink-count: 하드 링크 수'user-id: 소유자의 숫자 사용자 ID'group-id: 소유자의 숫자 그룹 ID'device-id-for-special-file: 장치 ID (특수 파일인 경우)'size: 파일 또는 심볼릭 링크의 크기(바이트)'block-size: 파일 시스템 블록 크기'block-count: 사용된 파일 시스템 블록 수'access-time-seconds: epoch 이후의 마지막 접근 시간(초)'modify-time-seconds: epoch 이후의 마지막 수정 시간(초)'change-time-seconds: epoch 이후의 마지막 상태 변경 시간(초)'creation-time-seconds: epoch 이후의 생성 시간(초)'access-time-nanoseconds: epoch 이후의 마지막 접근 시간(나노초)'modify-time-nanoseconds: epoch 이후의 마지막 수정 시간(나노초)'change-time-nanoseconds: epoch 이후의 마지막 상태 변경 시간(나노초)'creation-time-nanoseconds: epoch 이후의 생성 시간(나노초)
as-link?가 참 값이라면 path가 심볼릭 링크를 가리킬 때, 참조된 파일 시스템 항목의 stat 정보 대신 링크의 stat 정보가 반환됩니다.
모드 비트는 권한 및 기타 데이터를 위한 비트로, 각각 Posix stat/lstat 함수 또는 Windows _wstat64 함수에서 반환된 것입니다. 비트 패턴의 일부를 선택하려면 user-read-bit 등의 상수를 사용하세요.
운영체제와 파일 시스템에 따라 "나노초" 타임스탬프는 나노초보다 낮은 정밀도를 가질 수 있습니다. 예를 들어 한 환경에서 타임스탬프가 1234567891234567891(나노초 정밀도)일 수 있고, 다른 환경에서는 1234567891000000000(초 정밀도)일 수 있습니다.
플랫폼/파일 시스템 조합에서 사용할 수 없는 값은 0으로 설정될 수 있습니다. 예를 들어 Windows에서 'user-id와 'group-id 키에 적용됩니다. 또한 Posix 플랫폼은 상태 변경 타임스탬프는 제공하지만 생성 타임스탬프는 제공하지 않으며, Windows에서는 그 반대입니다.
as-link?가 #f이고 path에 접근할 수 없으면 exn:fail:filesystem 예외가 던져집니다. as-link?가 참 값이고 path를 해석할 수 없는 경우, 즉 매달린 링크(dangling link)인 경우에도 이 예외가 던져집니다.
base 패키지 버전 8.3.0.7에서 추가됨.
procedure
(file-or-directory-identity path [as-link?])
→ exact-positive-integer?
path : path-string?
as-link? : any/c = #f
path가 접근하는 장치와 파일 또는 디렉토리의 관점에서 path의 정체성(identity)을 나타내는 숫자를 반환해요. 이 함수는 경로의 항목 선택이 변하지 않는다는 가정 아래 두 경로가 동일한 파일 시스템 항목에 해당하는지 확인하는 데 사용할 수 있습니다.
as-link?가 참 값이라면 path가 파일 시스템 링크를 가리킬 때, (있다면) 참조된 파일 또는 디렉토리의 정체성 대신 링크의 정체성이 반환됩니다.
procedure
(file-size path) → exact-nonnegative-integer?
path : path-string?
지정된 파일의 (논리적) 크기를 바이트 단위로 반환해요. Mac OS에서 이 크기는 리소스 포크 크기를 제외합니다. 오류 시(예: 그런 파일이 없을 때) exn:fail:filesystem 예외가 던져집니다.
procedure
(copy-file src dest [exists-ok?/pos #:exists-ok? exists-ok?
#:permissions permissions #:replace-permissions? replace-permissions?])
→ void?
src : path-string?
dest : path-string?
exists-ok?/pos : any/c = #f
exists-ok? : any/c = exists-ok?/pos
permissions : (or/c #f (integer-in 0 65535)) = #f
replace-permissions? : any/c = #t
dest가 아직 존재하지 않으면 dest 파일을 src의 사본으로 만들어요. dest가 이미 존재하고 exists-ok?가 #f이면 복사는 실패하고 exn:fail:filesystem:exists? 예외가 던져지며, 그 외에는 dest가 존재하면 그 내용이 src의 내용으로 교체됩니다.
src가 링크를 가리키면 링크 자체가 아니라 링크의 대상이 복사됩니다. dest가 링크를 가리키고 exists-ok?가 참이면 링크의 대상이 갱신됩니다.
파일 권한은 src에서 dest로 전달되지만, Unix와 Mac OS에서 permissions가 #f가 아닌 값으로 제공되면 dest에 permissions가 사용됩니다. 권한이 기본적으로 프로세스의 umask 설정을 고려하지 않고 전달된다는 점에 주의하세요. 그러나 아래의 replace-permissions?를 보세요. Windows에서 src의 수정 시간도 dest로 전달됩니다. permissions가 #f가 아닌 값으로 제공되면 복사 후 dest는 permissions에 #o2 비트가 있는지에 따라 읽기 전용으로 설정되거나 그렇지 않습니다.
replace-permissions? 인자는 Unix와 Mac OS에서만 사용됩니다. dest가 생성될 때 요청된 권한 또는 src의 권한으로 생성되지만, 프로세스의 umask가 요청된 권한의 일부 비트를 해제할 수 있습니다. dest가 이미 존재할 때(그리고 exists-ok?가 참일 때) dest의 권한은 처음에는 그대로 남습니다. 마지막으로, replace-permissions?가 참 값이면 파일 내용이 복사된 후 dest의 권한이 umask에 의한 수정 없이 permissions 또는 src의 권한으로 설정됩니다.
위치 기반 인자 exists-ok?/pos는 하위 호환성을 위한 것입니다. 위치 기반 인자를 제공할 수도 있고 exists-ok? 키워드 인자를 제공할 수도 있지만, 둘 다 제공하면 exn:fail:contract 예외가 던져집니다.
base 패키지 버전 8.7.0.9에서 변경됨: #:exists-ok?, #:permissions, #:replace-permissions? 인자 추가.
procedure
(make-file-or-directory-link to path) → void?
to : path-string?
path : path-string?
to로 가는 링크 path를 만들어요. path가 이미 존재하면 생성은 실패합니다. to는 기존 파일이나 디렉토리를 가리킬 필요가 없으며, to는 링크를 쓰기 전에 확장되지 않습니다. 링크가 성공적으로 생성되지 않으면 exn:fail:filesystem 예외가 던져집니다.
Windows XP 및 이전 버전에서 exn:fail:unsupported 예외가 던져집니다. 이후 버전의 Windows에서는 링크 생성이 보안 정책에 의해 거부되는 경향이 있습니다. Windows는 파일 링크와 디렉토리 링크를 구분하며, to가 문법적으로 디렉토리로 파싱될 때만 (path->directory-path 참고) 디렉토리 링크가 생성됩니다. 또한 상대 경로 링크는 운영체제가 특별히 파싱합니다. 자세한 내용은 Windows Paths를 보세요. make-file-or-directory-link가 성공하면 junction이나 하드 링크가 아니라 심볼릭 링크를 만듭니다. 디렉토리 링크는 delete-file이 아니라 delete-directory로 삭제해야 한다는 점에 주의하세요.
base 패키지 버전 6.0.1.12에서 변경됨: Windows에서 링크 지원 추가.
parameter
(current-force-delete-permissions) → boolean?
(current-force-delete-permissions force?) → void?
force? : any/c
= #t
Windows에서 delete-file과 delete-directory가 파일이나 디렉토리를 삭제하기 위해 그 권한을 바꾸려 시도할지 여부를 결정하는 파라미터예요. 기본값은 #t입니다.
디렉토리 (Directories)
또한 보세요: rename-file-or-directory, file-or-directory-modify-seconds, file-or-directory-permissions.
parameter
(current-directory) → (and/c path? complete-path?)
(current-directory path) → void?
path : path-string?
상대 경로를 해석하기 위한 현재 디렉토리를 결정하는 파라미터예요.
현재 디렉토리를 설정하기 위해 파라미터 프로시저가 호출되면, path 인자는 cleanse-path로 정리(cleanse)되고, simplify-path로 단순화된 다음, path->directory-path로 디렉토리 경로로 변환됩니다. 정리와 단순화는 경로가 잘못 형성되어 있으면 예외를 던집니다. 따라서 current-directory의 현재 값은 항상 정리되고, 단순화되고, 완전한 디렉토리 경로입니다.
파라미터를 설정할 때 경로의 존재 여부는 검사되지 않습니다.
Unix와 Mac OS에서 Racket 프로세스의 파라미터 초기 값은 PWD 환경 변수에서 가져옵니다. 단, 환경 변수의 값이 운영체제가 보고하는 현재 디렉토리와 같은 디렉토리를 식별할 때만 그렇습니다.
parameter
(current-directory-for-user) → (and/c path? complete-path?)
(current-directory-for-user path) → void?
path : path-string?
current-directory와 같지만, 디렉토리에 상대적인 경로를 보고하기 위한 srcloc->string이 사용하는 용도로만 사용돼요.
보통 current-directory-for-user는 초기 값에 머물러 있어야 하며, 사용자가 프로세스를 시작한 디렉토리를 반영합니다. 다만 DrRacket 같은 도구는 사용자가 (편집 중인 파일에 대해) 디렉토리를 암묵적으로 선택하게 하며, 그런 경우 current-directory-for-user를 갱신하는 것이 타당합니다.
procedure
(current-drive) → path?
Windows의 현재 드라이브 이름을 반환해요. 다른 플랫폼에서는 exn:fail:unsupported 예외가 던져집니다. 현재 드라이브는 항상 현재 디렉토리의 드라이브입니다.
procedure
(directory-exists? path) → boolean?
path : path-string?
path가 디렉토리를 가리키면 #t를, 그렇지 않으면 #f를 반환해요.
procedure
(make-directory path [permissions]) → void?
path : path-string?
permissions : (integer-in 0 65535) = #o777
path라는 새 디렉토리를 만들어요. 디렉토리가 성공적으로 생성되지 않으면 exn:fail:filesystem 예외가 던져집니다.
permissions 인자는 생성된 디렉토리의 권한을 지정하며, 여기서 권한의 정수 표현은 file-or-directory-permissions와 동일하게 취급됩니다. Unix와 Mac OS에서 이 권한 비트는 프로세스의 umask와 결합됩니다. Windows에서는 permissions가 사용되지 않습니다.
base 패키지 버전 8.3.0.5에서 변경됨: permissions 인자 추가.
procedure
(delete-directory path) → void?
path : path-string?
path라는 기존 디렉토리를 삭제해요. 디렉토리가 성공적으로 삭제되지 않으면 exn:fail:filesystem 예외가 던져집니다.
Windows에서 디렉토리 삭제의 초기 시도가 권한 오류로 실패하고 current-force-delete-permissions의 값이 참이면, delete-file은 디렉토리의 권한을 (쓰기가 허용되도록) 바꾼 뒤 디렉토리를 삭제하려 합니다. 권한 변경 후 삭제는 비원자적 시퀀스이며, 삭제가 실패해도 권한 변경을 되돌리려는 시도는 없습니다.
base 패키지 버전 6.1.1.7에서 변경됨: Windows 동작이 current-force-delete-permissions를 사용하도록 변경.
procedure
(directory-list [path #:build? build?]) → (listof path?)
path : path-string? = (current-directory)
build? : any/c = #f
in-directory 시퀀스 생성자도 함께 보세요.
path가 지정하는 디렉토리 안의 모든 파일과 디렉토리의 리스트를 반환해요. build?가 #f이면 결과 경로는 모두 경로 요소(path element)이고, 그 외에는 개별 결과가 build-path를 사용해 path와 결합됩니다. Windows에서 결과 리스트의 한 요소는 \\?\REL\로 시작할 수 있습니다.
결과 경로는 항상 path<?를 사용해 정렬됩니다.
procedure
(filesystem-root-list) → (listof path?)
모든 현재 루트 디렉토리의 리스트를 반환해요. 이 리스트를 얻는 것은 Windows에서 특히 느릴 수 있습니다.
파일 시스템 변경 감지 (Detecting Filesystem Changes)
많은 운영체제가 파일 시스템 변경에 대한 알림을 제공하며, 그 알림은 Racket에서 파일 시스템 변경 이벤트(filesystem change event)로 반영돼요.
procedure
(filesystem-change-evt? v) → boolean?
v : any/c
v가 파일 시스템 변경 이벤트이면 #t를, 그렇지 않으면 #f를 반환해요.
procedure
(filesystem-change-evt path [failure-thunk])
→ (or/c filesystem-change-evt? any)
path : path-string?
failure-thunk : (or/c (-> any) #f) = #f
파일 시스템 변경 이벤트를 만들어요. 이는 path에 대한 변경 후 동기화(synchronization) 준비가 되는 동기화 가능 이벤트(synchronizable event)입니다:
path가 파일을 가리키면, 파일의 내용이나 속성이 변경되거나 파일이 삭제될 때 이벤트가 동기화 준비가 됩니다.path가 디렉토리를 가리키면, 디렉토리 안에서 파일이나 하위 디렉토리가 추가, 이름 변경, 또는 제거될 때 이벤트가 동기화 준비가 됩니다.
이벤트가 filesystem-change-evt-cancel에 전달되면 이벤트도 동기화 준비가 됩니다.
마지막으로, 운영체제에서 얻을 수 있는 정보의 정밀도에 따라 이벤트는 다른 상황에서도 동기화 준비가 될 수 있습니다. 예를 들어 Windows에서 파일에 대한 이벤트는 파일과 같은 디렉토리 안에서 어떤 파일이든 변경되면 준비가 됩니다.
파일 시스템 변경 이벤트가 동기화 준비가 된 후에는 계속 준비 상태로 남습니다. 이벤트의 동기화 결과는 이벤트 자신입니다.
현재 플랫폼이 파일 시스템 변경 알림을 지원하지 않으면, failure-thunk가 프로시저로 제공되지 않을 때 exn:fail:unsupported 예외가 던져지고, 제공되면 failure-thunk가 꼬리 위치에서 호출됩니다. 마찬가지로 이벤트 생성 시 운영체제 오류(존재하지 않는 파일 같은)가 있으면 exn:fail:filesystem 예외가 던져지거나 failure-thunk가 호출됩니다.
파일 시스템 변경 이벤트를 생성하면 운영체제 수준에서 리소스가 할당됩니다. 그 리소스는 이벤트가 동기화되고 동기화 준비가 되었을 때, filesystem-change-evt-cancel로 이벤트가 취소되었을 때, 또는 가비지 컬렉터가 파일 시스템 변경 이벤트가 도달 불가능하다고 판단할 때 가장 늦게 해제됩니다. 'fs-change 모드의 system-type도 함께 보세요.
파일 시스템 변경 이벤트는 생성될 때 현재 custodian의 관리 아래 놓입니다. custodian이 종료되면 filesystem-change-evt-cancel이 이벤트에 적용됩니다.
base 패키지 버전 7.3.0.8에서 변경됨: failure-thunk에 #f 허용.
procedure
(filesystem-change-evt-ready? evt) → boolean?
evt : filesystem-change-evt?
(and (sync/timeout 0 evt) #t)와 동등해요.
base 패키지 버전 8.18.0.6에서 추가됨.
procedure
(filesystem-change-evt-cancel evt) → void?
evt : filesystem-change-evt?
evt가 이전에 준비 상태였는지 여부와 무관하게 즉시 동기화 준비가 되게 하고, 파일 시스템 변경을 추적하기 위한 (운영체제 수준의) 리소스를 해제해요.
실행 시점에 필요한 경로 선언 (Declaring Paths Needed at Run Time)
(require racket/runtime-path) package: base
이 섹션에서 문서화된 바인딩은 racket/runtime-path 라이브러리가 제공하며, racket/base나 racket이 제공하지 않아요.
racket/runtime-path 라이브러리는 보통 둘러싼 소스 파일에 상대적인 경로를 사용해 실행 시점에 파일과 디렉토리에 접근하는 폼을 제공해요. collection-path를 사용하는 것과 달리, define-runtime-path는 각 실행 시점 경로를 실행 파일 및 배포 생성자 같은 도구에 노출하므로, 실행 시점에 필요한 파일과 디렉토리가 배포물에 함께 실려 갑니다.
아래에 설명된 바인딩 외에도 racket/runtime-path는 phase 레벨 1에서 #%datum을 제공하는데, 문자열 상수가 define-runtime-path와 함께 컴파일-시점 표현식으로 자주 사용되기 때문입니다.
syntax
(define-runtime-path id maybe-runtime?-id expr)
maybe-runtime?-id = | #:runtime?-id runtime?-id
expr을 컴파일-시점(즉 phase 1) 표현식이자 실행-시점(즉 phase 0) 표현식으로 모두 사용해요. 두 컨텍스트 모두에서 expr은 경로, 경로를 나타내는 문자열, (list 'lib str ...+) 형태의 리스트, 또는 (list 'so str)이나 (list 'so str vers) 형태의 리스트를 만들어야 합니다. runtime?-id가 제공되면 그것은 expr의 컨텍스트에서 expr의 컴파일-시점 인스턴스에 대해서는 #f로, 실행-시점 인스턴스에 대해서는 #t로 바인딩됩니다.
실행 시점에서 id는 expr의 결과에 기반한 경로에 바인딩됩니다. 그 경로는 보통 expr의 상대 경로 결과를 취해 그것을 둘러싼 파일의 경로에 더해 계산됩니다(그 경로는 아래에서 설명하듯 계산됩니다). 그러나 실행 파일 생성자 같은 도구는 (racket/runtime-path와 짜고) 생성된 실행 파일에 다른 기본 경로가 대입되도록 마련할 수도 있습니다. expr이 절대 경로를 만들면 보통 그대로 반환되지만, 역시 실행 파일 생성자가 교체할 수 있습니다. 모든 경우에 실행 파일 생성자는 주어진 패키지 안의 모든 경로의 상대적 위치를 보존합니다(패키지 밖의 경로는 함께 있는 것으로 취급). expr이 상대 또는 절대 경로를 만들 때 id에 바인딩된 경로는 항상 절대 경로입니다.
expr이 (list 'lib str ...+) 형태의 리스트를 만들면 id에 바인딩된 값은 절대 경로입니다. 그 경로는 그 값을 모듈 경로로 사용하는 것과 유사하게 컬렉션 기반 파일을 가리킵니다.
expr이 (list 'so str)이나 (list 'so str vers) 형태의 리스트를 만들면 id에 바인딩된 값은 str이거나 절대 경로일 수 있습니다. Racket 특화 공유-오브젝트 라이브러리 디렉토리(가 get-lib-search-dirs로 결정되는)에서의 검색이 그 경로를 찾으면 절대 경로입니다. 이런 식으로 Racket을 위해 특별히 설치된 공유-오브젝트 라이브러리가 배포물에 함께 실려 갑니다. 검색은 각 디렉토리를 순서대로 시도합니다. 디렉토리 안에서 검색은 str을 직접 사용해 시도한 다음, vers가 지정하는 각 버전 — 기본값은 '(#f) — 을 (system-type 'so-suffix)가 만들어내는 플랫폼별 공유-라이브러리 확장자와 함께 더해 시도합니다. vers는 문자열이거나 문자열과 #f의 리스트일 수 있습니다.
expr이 (list 'share str) 형태의 리스트를 만들면 id에 바인딩된 값은 str이거나 절대 경로일 수 있습니다. find-user-share-dir와 find-share-dir(그 순서로)이 보고하는 디렉토리에서의 검색이 그 경로를 찾으면 절대 경로입니다. 이런 식으로 Racket의 "share" 디렉토리에 설치된 파일이 배포물에 함께 실려 갑니다.
expr이 (list 'module module-path var-ref)이나 (list 'so str (list str-or-false ...)) 형태의 리스트를 만들면 id에 바인딩된 값은 모듈 경로 인덱스(module path index)이며, 여기서 module-path는 변수 참조 var-ref의 홈인 모듈에 대해 (상대적이라면) 상대적으로 취급되고, module-path가 절대적이면 var-ref는 #f일 수 있습니다. 실행 파일에서 해당 모듈은 모든 의존성을 포함해 함께 실려 갑니다.
컴파일-시점에서 expr 결과는 실행 파일 생성자가 사용하지만, 포함하는 모듈이 컴파일될 때의 결과는 아닙니다. 대신 expr은 컴파일-시점 표현식으로 모듈 안에 보존됩니다(begin-for-syntax의 의미로). 나중에 실행 파일이 생성될 때 모듈의 컴파일-시점 부분이 (다시) 실행되고, expr의 결과는 실행 파일에 포함될 파일 또는 디렉토리입니다. 추가 컴파일-시점 실행의 이유는 expr의 결과가 플랫폼 의존적일 수 있으므로, 그 결과를 (플랫폼 독립적인) 모듈의 바이트코드 형태에 저장해서는 안 되기 때문입니다. 다만 실행 파일 생성 시점의 플랫폼은 실행 파일의 실행 시점과 같습니다. expr은 여전히 실행 시점에 평가된다는 점에 주의하세요. 따라서 소스 설치에 의존하는 collection-path 같은 프로시저는 피하고, 대신 상대 경로와 (list 'lib str ...+) 같은 폼을 사용하세요.
경로가 일부 플랫폼에서만 필요하다면, 경로가 필요하지 않은 플랫폼에서 빈 리스트를 만드는 expr과 함께 define-runtime-path-list를 사용하세요.
실행 파일을 만들 때 expr이 디렉토리의 경로를 만들면, 그 디렉토리의 전체 내용(하위 디렉토리 포함)이 실행 파일 또는 최종 배포물에 포함된다는 점에 주의하세요.
또한 phase 레벨 0이 아닌 곳의 define-runtime-path는 실행 파일 생성자와 제대로 협력하지 않는다는 점에 주의하세요. 그 한계를 피하려면 define-runtime-path를 별도의 모듈 — 어쩌면 module이 만든 하위 모듈 — 에 넣어 정의를 내보낸 다음, 그 정의를 담은 모듈을 어떤 phase 레벨에서든 require할 수 있게 하세요. phase 레벨 0이 아닌 곳에서 define-runtime-path를 사용하면 확장 시점에 경고가 기록됩니다.
define-runtime-path의 둘러싼 경로는 define-runtime-path 구문 폼으로부터 다음과 같이 결정됩니다:
syntax-source-module에 따른 소스 모듈이 폼에 있으면, 원본 표현식을 syntax 객체로 보존하고 실행 시점에 그 소스 모듈 경로를 추출해(다시syntax-source-module을 사용) 결과 모듈 경로 인덱스를 해석해 소스 위치를 결정합니다.syntax-source-module은 syntax 객체의 어휘 정보에 기반하며, 소스 위치에 기반하지 않는다는 점에 주의하세요.- 표현식에 소스 모듈이 없으면, 폼과 연관된
syntax-source위치를 사용합니다(문자열 또는 경로인 경우). - 소스 모듈을 사용할 수 없고
syntax-source가 경로를 만들지 않으면,current-load-relative-directory가#f가 아닐 때 그것을 사용합니다. 마지막으로, 다른 모든 것이 실패하면current-directory를 사용합니다.
후자의 두 경우에서 경로는 보통 (플랫폼 특화된) 바이트 형태로 보존되지만, 둘러싼 경로가 collection-file-path의 결과에 해당하면 그 경로는 해당 모듈 경로에 상대적인 것으로 기록됩니다.
base 패키지 버전 6.0.1.6에서 변경됨: 패키지 안에서만 상대 경로 보존. 버전 7.5.0.7에서 변경됨: expr에서 'share 지원 추가.
예:
; 모듈 소스 파일과 같은 디렉토리에 원래 있는
; 실행-시점 파일 "data.txt"에 접근하기:
(define-runtime-path data-file "data.txt")
(define (read-data)
(with-input-from-file data-file
(lambda ()
(read-bytes (file-size data-file)))))
; 모듈의 소스 디렉토리의 플랫폼별 하위 디렉토리에 있는
; 플랫폼 특화 공유 오브젝트를 (ffi-lib로) 로드하기:
(define-runtime-path libfit-path
(build-path "compiled" "native" (system-library-subpath #f)
(path-replace-suffix "libfit"
(system-type 'so-suffix))))
(define libfit (ffi-lib libfit-path))
; 운영체제의 일부로 설치되었을 수도 있고,
; Racket을 위해 특별히 설치되었을 수도 있는
; 플랫폼 특화 공유 오브젝트를 로드하기:
(define-runtime-path libssl-so
(case (system-type)
[(windows) '(so "ssleay32")]
[else '(so "libssl")]))
(define libssl (ffi-lib libssl-so))
base 패키지 버전 6.4에서 변경됨: #:runtime?-id 추가.
syntax
(define-runtime-paths (id ...) maybe-runtime?-id expr)
define-runtime-path와 같지만, 여러 경로를 한 번에 선언하고 바인딩해요. expr은 id 수만큼의 값을 만들어야 합니다.
syntax
(define-runtime-path-list id maybe-runtime?-id expr)
define-runtime-path와 같지만, expr은 경로 리스트를 만들어야 해요.
syntax
(define-runtime-module-path-index id maybe-runtime?-id module-path-expr)
define-runtime-path와 비슷하지만, id는 module-path-expr의 결과를 둘러싼 모듈에 상대적으로 캡슐화한 모듈 경로 인덱스에 바인딩돼요.
define-runtime-module-path-index를 사용해 dynamic-require 같은 반영적(reflective) 함수에 전달되는 모듈 경로를 바인딩하면서 동시에 실행 파일 빌드 및 배포를 위한 모듈 의존성을 만들 수 있어요.
syntax
(runtime-require module-path)
define-runtime-module-path-index와 비슷하지만, 모듈 경로 인덱스를 바인딩하지 않고 배포 의존성을 만들어요. 모듈 안에서 runtime-require가 같은 module-path로 여러 번 사용되면 첫 번째 사용을 제외한 모두가 빈 begin으로 확장됩니다.
syntax
(define-runtime-module-path id module-path)
define-runtime-path와 비슷하지만, id는 해석된 모듈 경로에 바인딩돼요. id의 해석된 모듈 경로는 module-path에 해당하며(require를 위한 모듈 경로와 같은 문법), 그것은 둘러싼 모듈에 상대적일 수 있습니다.
define-runtime-module-path-index 폼이 보통 선호되는데, 그것이 참조된 모듈에 더 약한 연결을 만들기 때문입니다. define-runtime-module-path-index와 달리 define-runtime-module-path 폼은 둘러싼 모듈에서 module-path로의 for-label 의존성을 만듭니다. 의존성이 단지 for-label이므로 module-path는 둘러싼 모듈이 인스턴스화되거나 방문될 때 인스턴스화되거나 방문되지 않지만(다른 require가 그런 의존성을 만들지 않는 한), 참조된 모듈의 코드는 둘러싼 모듈이 로드될 때 로드됩니다.
syntax
(runtime-paths module-path)
이 폼은 주로 실행 파일 빌더 같은 도구가 사용하기 위한 것입니다. 그것은 module-path가 선언한 실행 시점 경로를 담은 따옴표 리스트로 확장되며, 선언 expr의 컴파일-시점 결과를 반환합니다. 단, 경로는 바이트 문자열로 변환됩니다. 둘러싼 모듈은 module-path가 지정하는(따옴표 없이 쓰여진 모듈 경로) 모듈을 (직접 또는 간접적으로) require해야 합니다. 결과 리스트는 define-runtime-module-path로 바인딩된 모듈 경로는 포함하지 않습니다.
더 많은 파일과 디렉토리 유틸리티 (More File and Directory Utilities)
(require racket/file) package: base
이 섹션에서 문서화된 바인딩은 racket/file과 racket 라이브러리가 제공하며, racket/base는 제공하지 않아요.
procedure
(file->string path [ #:mode mode-flag ]) → string?
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
path에서 모든 문자를 읽어 문자열로 반환해요. mode-flag 인자는 open-input-file의 것과 같습니다.
procedure
(file->bytes path [ #:mode mode-flag ]) → bytes?
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
path에서 모든 문자를 읽어 바이트 문자열로 반환해요. mode-flag 인자는 open-input-file의 것과 같습니다.
procedure
(file->value path [ #:mode mode-flag ]) → any
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
read를 사용해 path에서 단일 S-표현식을 읽어요. mode-flag 인자는 open-input-file의 것과 같습니다.
procedure
(file->list path [ proc #:mode mode-flag ]) → (listof any/c)
path : path-string?
proc : (input-port? . -> . any/c) = read
mode-flag : (or/c 'binary 'text) = 'binary
proc을 반복적으로 호출해 path의 내용을 eof가 만들어질 때까지 소비해요. mode-flag 인자는 open-input-file의 것과 같습니다.
procedure
(file->lines path [ #:mode mode-flag #:line-mode line-mode ])
→ (listof string?)
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
line-mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one) = 'any
path에서 모든 문자를 읽어 줄로 나눠요. line-mode 인자는 read-line의 두 번째 인자와 같지만, 기본값은 'linefeed가 아니라 'any입니다. mode-flag 인자는 open-input-file의 것과 같습니다.
procedure
(file->bytes-lines path [ #:mode mode-flag #:line-mode line-mode ])
→ (listof bytes?)
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
line-mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one) = 'any
file->lines와 같지만, 바이트를 읽어 read-bytes-line처럼 줄로 모읍니다.
procedure
(display-to-file v path [ #:mode mode-flag #:exists exists-flag ])
→ void?
v : any/c
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
exists-flag : (or/c 'error 'append 'update 'replace 'truncate 'truncate/replace)
= 'error
display를 사용해 v를 path에 출력해요. mode-flag와 exists-flag 인자는 open-output-file의 것과 같습니다.
procedure
(write-to-file v path [ #:mode mode-flag #:exists exists-flag ])
→ void?
v : any/c
path : path-string?
mode-flag : (or/c 'binary 'text) = 'binary
exists-flag : (or/c 'error 'append 'update 'replace 'truncate 'truncate/replace)
= 'error
display 대신 write를 사용한다는 점만 빼면 display-to-file과 같아요.
procedure
(display-lines-to-file lst path [ #:separator separator #:mode mode-flag
#:exists exists-flag ]) → void?
lst : list?
path : path-string?
separator : any/c = #"\n"
mode-flag : (or/c 'binary 'text) = 'binary
exists-flag : (or/c 'error 'append 'update 'replace 'truncate 'truncate/replace)
= 'error
lst의 각 요소를 path에 표시하고, 각 요소 뒤에 separator를 추가해요. mode-flag와 exists-flag 인자는 open-output-file의 것과 같습니다.
procedure
(copy-directory/files src dest [ #:keep-modify-seconds? keep-modify-seconds?
#:preserve-links? preserve-links? ]) → void?
src : path-string?
dest : path-string?
keep-modify-seconds? : any/c = #f
preserve-links? : any/c = #f
파일 또는 디렉토리 src를 dest로 복사하며, 아마도 dest가 이미 존재하기 때문에 파일이나 디렉토리를 복사할 수 없으면 exn:fail:filesystem을 던져요. src가 디렉토리이면 복사는 디렉토리의 내용에 재귀적으로 적용됩니다. 소스가 링크이고 preserve-links?가 #f이면 링크 자체가 아니라 링크의 대상이 복사되고, preserve-links?가 #t이면 링크가 복사됩니다.
keep-modify-seconds?가 #f이면 파일 복사는 copy-file이 유지하는 속성만 유지합니다. keep-modify-seconds?가 참이면 각 파일 복사는 원본의 수정 날짜도 유지합니다.
base 패키지 버전 6.3에서 변경됨: #:preserve-links? 인자 추가.
procedure
(delete-directory/files path [ #:must-exist? must-exist? ]) → void?
path : path-string?
must-exist? : any/c = #t
path가 지정하는 파일 또는 디렉토리를 삭제하며, 파일이나 디렉토리를 삭제할 수 없으면 exn:fail:filesystem을 던져요. path가 디렉토리이면 디렉토리가 삭제되기 전에 path의 각 파일과 디렉토리에 delete-directory/files가 먼저 적용됩니다.
must-exist?가 참이면 path가 존재하지 않을 때 exn:fail:filesystem이 던져집니다. must-exist?가 거짓이면 path가 존재하지 않을 때 delete-directory/files는 성공합니다(하지만 path가 처음에 존재했고 delete-directory/files가 삭제하기 전에 다른 스레드나 프로세스가 제거하는 경우 실패할 수 있습니다).
Windows에서 delete-directory/files는 파일을 삭제하기 전에 임시-파일 디렉토리로 옮기려 시도하며, 이는 (백그라운드 프로세스로 실행되는 검색 인덱서 같은 것이) 현재 열려 있는 파일 삭제로 인한 문제를 피합니다. 이동 시도가 실패하면(예: 임시 디렉토리가 파일과 다른 드라이브에 있을 때) 파일은 delete-file로 직접 삭제됩니다.
base 패키지 버전 7.0에서 변경됨: Windows 특화 파일 삭제 추가.
procedure
(find-files predicate [ start-path
#:skip-filtered-directory? skip-filtered-directory?
#:follow-links? follow-links? ]) → (listof path?)
predicate : (path? . -> . any/c)
start-path : (or/c path-string? #f) = #f
skip-filtered-directory? : any/c = #f
follow-links? : any/c = #f
start-path에서 시작해 파일 시스템을 탐색하며 predicate가 참을 반환하는 모든 파일과 디렉토리의 리스트를 만들어요. start-path가 #f이면 탐색은 (current-directory)에서 시작합니다. 결과 리스트에서 각 디렉토리는 그 내용보다 앞에 옵니다.
predicate 프로시저는 각 파일 또는 디렉토리에 대해 단일 인자로 호출됩니다. start-path가 #f이면 그 인자는 현재 디렉토리에 상대적인 경로명 문자열입니다. 그 외에는 start-path를 기반으로 만든 경로입니다. 결과적으로 start-path에 (current-directory)를 제공하는 것은 #f를 제공하는 것과 다른데, 전자의 경우 predicate가 완전한 경로를 받고 후자의 경우 상대 경로를 받기 때문입니다. 또 다른 차이는 start-path가 #f일 때 현재 디렉토리에 대해 predicate가 호출되지 않는다는 것입니다.
skip-filtered-directory?가 참이면 predicate가 디렉토리에 대해 #f를 반환할 때 그 디렉토리의 내용은 탐색되지 않습니다.
follow-links?가 참이면 find-files 탐색은 링크를 따라가며, 링크는 결과에 포함되지 않습니다. follow-links?가 #f이면 링크는 따라가지 않으며, 링크가 결과에 포함됩니다.
start-path가 기존 파일이나 디렉토리를 가리키지 않으면 predicate는 start-path를 인자로 정확히 한 번 호출됩니다.
find-files 프로시저는 directory-list가 실패하는 디렉토리를 만나면 예외를 던집니다.
base 패키지 버전 6.3.0.11에서 변경됨: #:skip-filtered-directory? 인자 추가.
procedure
(pathlist-closure path-list [ #:path-filter path-filter
#:follow-links? follow-links? ]) → (listof path?)
path-list : (listof path-string?)
path-filter : (or/c #f (path? . -> . any/c)) = #f
follow-links? : any/c = #f
경로 리스트가 주어지면(절대적이거나 현재 디렉토리에 상대적), 다음을 만족하는 리스트를 반환해요:
- 중첩된 경로가 주어지면 그 조상도 모두 결과에 포함됩니다(단, 같은 조상은 두 번 추가되지 않습니다).
- 경로가 디렉토리를 가리키면 그 하위 항목도 모두 결과에 포함됩니다. 단,
path-filter가 생략한 항목은 제외됩니다. - 조상 디렉토리는 주어진
path-list에서 순서가 잘못되지 않았다면 결과 리스트에서 그 하위 항목보다 앞에 옵니다.
path-filter가 프로시저이면 디렉토리의 각 하위 항목에 적용됩니다. path-filter가 #f를 반환하면 그 하위 항목(하위 디렉토리인 경우 그 하위 항목들도)은 결과에서 생략됩니다.
follow-links?가 참이면 디렉토리와 파일의 탐색이 링크를 따라가며, 링크 경로는 결과에 포함되지 않습니다. follow-links?가 #f이면 결과 리스트는 링크에 대한 경로를 포함하고 링크는 따라가지 않습니다.
base 패키지 버전 6.3.0.11에서 변경됨: #:path-filter 인자 추가.
procedure
(fold-files proc init-val [ start-path follow-links? ]) → any
proc :
(or/c (path? (or/c 'file 'dir 'link) any/c . -> . any/c)
(path? (or/c 'file 'dir 'link) any/c . -> . (values any/c any/c)))
init-val : any/c
start-path : (or/c path-string? #f) = #f
follow-links? : any/c = #t
start-path에서 시작해 파일 시스템을 탐색하며, 발견된 각 파일, 디렉토리, 링크에 proc을 호출해요. start-path가 #f이면 탐색은 (current-directory)에서 시작합니다.
proc 프로시저는 각 파일, 디렉토리, 또는 링크에 대해 세 개의 인자로 호출됩니다:
start-path가#f이면 첫 번째 인자는 현재 디렉토리에 상대적인 경로명 문자열입니다. 그 외에는 첫 번째 인자는start-path로 시작하는 경로명입니다. 결과적으로start-path에(current-directory)를 제공하는 것은#f를 제공하는 것과 다른데, 전자의 경우proc이 완전한 경로를 받고 후자의 경우 상대 경로를 받기 때문입니다. 또 다른 차이는start-path가#f일 때 현재 디렉토리에 대해proc이 호출되지 않는다는 것입니다.- 두 번째 인자는
'file,'dir, 또는'link중 하나인 심볼입니다.follow-links?가#f이면 두 번째 인자는'link일 수 있는데, 이 경우 파일 시스템 탐색은 링크를 따라가지 않습니다.follow-links?가#t이면proc은 매달린 심볼릭 링크(기존 파일이나 디렉토리로 해석되지 않는 것)를 만났을 때만 두 번째 인자로'link를 받습니다. - 세 번째 인자는 누적된 결과입니다.
proc의 첫 번째 호출에서 세 번째 인자는init-val입니다.proc의 두 번째 호출(있다면)에서 세 번째 인자는 첫 번째 호출의 결과이며, 이런 식으로 이어집니다. 마지막proc호출의 결과가fold-files의 결과입니다.
proc 인자는 foldl의 프로시저 인자와 유사하게 사용되며, 여기서 그 결과는 새 누적 결과로 사용됩니다. 디렉토리의 경우(두 번째 인자가 'dir일 때) 예외가 있습니다. 이 경우 프로시저는 두 값을 반환할 수 있는데, 두 번째 값은 재귀 스캔이 주어진 디렉토리를 포함해야 하는지 여부를 나타냅니다. 단일 값을 반환하면 그 디렉토리는 스캔됩니다. 파일 또는 링크의 경우(두 번째 인자가 'file 또는 'link일 때) 두 번째 값은 허용되지만 무시됩니다.
start-path가 제공되었지만 그런 경로가 존재하지 않거나, 스캔 중에 경로가 사라지면 예외가 던져집니다.
procedure
(make-directory* path) → void?
path : path-string?
path가 지정하는 디렉토리를 만들며, 필요하면 중간 디렉토리도 만들고, path가 이미 존재하면 절대 실패하지 않아요.
path가 상대 경로이고 현재 디렉토리가 존재하지 않으면 make-directory*는 현재 디렉토리를 만들지 않는데, path의 명시적 요소만 고려하기 때문입니다.
procedure
(make-parent-directory* path) → void?
path : path-string?
path가 지정하는 경로의 부모 디렉토리를 만들며, 필요하면 중간 디렉토리도 만들고, path의 조상이 이미 존재하면 절대 실패하지 않아요.
path가 파일 시스템 루트이거나 단일 경로 요소를 가진 상대 경로이면 어떤 디렉토리도 만들어지지 않습니다. make-directory*처럼, path가 상대 경로이고 현재 디렉토리가 존재하지 않으면 make-parent-directory*도 그것을 만들지 않습니다.
base 패키지 버전 6.1.1.3에서 추가됨.
procedure
(make-temporary-file [ template #:copy-from copy-from #:base-dir base-dir
compat-copy-from compat-base-dir ]) → (and/c path? complete-path?)
template : string? = "rkttmp~a"
copy-from : (or/c path-string? #f 'directory) = #f
base-dir : (or/c path-string? #f) = #f
compat-copy-from : (or/c path-string? #f 'directory) = copy-from
compat-base-dir : (or/c path-string? #f) = base-dir
새 임시 파일을 만들고 그 경로를 반환해요. 단순히 새 파일 이름을 생성하는 대신 파일이 실제로 생성되는데, 이는 다른 스레드나 프로세스가 같은 임시 이름을 고르지 못하게 합니다.
template 인자는 format과 추가 문자열 인자 하나(숫자만 담게 될)와 함께 사용하기에 적합한 포맷 문자열이어야 합니다. 기본적으로 template이 상대 경로를 만들면 build-path를 사용해 (find-system-path 'temp-dir)의 결과와 결합됩니다. 또는 template이 절대 경로를 만들 수도 있는데, 그 경우 (find-system-path 'temp-dir)는 참고되지 않습니다. base-dir가 제공되고 #false가 아니면 template은 완전한 경로를 만들어서는 안 되며, base-dir가 (find-system-path 'temp-dir) 대신 사용됩니다. base-dir를 사용하는 것이 일반적으로 template에 디렉토리 요소를 포함하는 것보다 더 신뢰할 수 있습니다. 경로를 문자열로 조작하는 미묘한 버그를 피하고 포맷 이스케이프 시퀀스를 정리해야 할 필요를 없애기 때문입니다.
Windows에서 template은 완전한 경로가 아닌 절대 경로(Windows Paths 참고)를 만들 수 있는데, 이는 base-dir가 없거나 #f일 때(그 경우 (current-directory)에 상대적으로 해석됩니다) 또는 base-dir가 드라이브 지정일 때(그 경우 build-path처럼 사용됩니다)입니다. base-dir가 다른 종류의 경로라면 template이 절대 경로를 만드는 것은 오류입니다.
template 인자가 제공되지 않으면, make-temporary-file 호출 지점에 대한 소스 위치 정보가 있다면 소스 위치에 기반한 템플릿 문자열이 생성됩니다. 기본값 "rkttmp~a"는 소스 위치 정보를 사용할 수 없을 때만 사용됩니다(예: make-temporary-file이 고차 위치에서 사용될 때).
copy-from이 경로로 제공되면 임시 파일은 이름 있는 파일의 사본으로 생성됩니다(copy-file 사용). copy-from이 #f이면 임시 파일은 빈 파일로 생성됩니다. 특수한 경우로, 하위 호환성을 위해 copy-from이 'directory이면 임시 "파일"은 디렉토리로 생성됩니다. 명확성을 위해 임시 디렉토리를 만들 때는 make-temporary-directory를 선호하세요.
임시 파일이 생성될 때 경로가 반환될 때 읽기나 쓰기용으로 열리지는 않습니다. make-temporary-file을 호출하는 클라이언트 프로그램은 원하는 접근 및 플래그로 파일을 열고(아마도 'truncate 플래그 사용; open-output-file 참고) 더 이상 필요 없을 때 삭제할 것으로 기대됩니다.
위치 기반 인자 compat-copy-from과 compat-base-dir는 하위 호환성을 위한 것입니다. 제공되면 #:copy-from과 #:base-dir 키워드 변형보다 우선합니다. 위치 기반 인자를 제공하면 make-temporary-file이 소스 위치를 사용해 템플릿을 생성하는 것을 막습니다.
base 패키지 버전 8.4.0.3에서 변경됨: #:copy-from과 #:base-dir 인자 추가.
procedure
(make-temporary-directory [ template #:base-dir base-dir ])
→ (and/c path? complete-path?)
template : string? = "rkttmp~a"
base-dir : (or/c path-string? #f) = #f
make-temporary-file과 같지만, 일반 파일이 아니라 디렉토리를 만들어요.
make-temporary-file과 마찬가지로 template 인자가 제공되지 않으면 가능할 때 make-temporary-directory 호출의 소스 위치에서 템플릿 문자열이 생성됩니다. 기본값 "rkttmp~a"는 소스 위치 정보를 사용할 수 없을 때만 사용됩니다.
base 패키지 버전 8.4.0.3에서 추가됨.
procedure
(make-temporary-file* prefix suffix [ #:copy-from copy-from #:base-dir base-dir ])
→ (and/c path? complete-path?)
prefix : bytes?
suffix : bytes?
copy-from : (or/c path-string? #f) = #f
base-dir : (or/c path-string? #f) = #f
procedure
(make-temporary-directory* prefix suffix [ #:base-dir base-dir ])
→ (and/c path? complete-path?)
prefix : bytes?
suffix : bytes?
base-dir : (or/c path-string? #f) = #f
각각 make-temporary-file과 make-temporary-directory와 같지만, 포맷을 위한 템플릿을 사용하는 대신 경로는 (bytes-append prefix generated suffix)에 기반하며, 여기서 generated는 고유한 경로를 만들기 위해 구현이 선택하는 바이트 문자열입니다. make-temporary-file*이나 make-temporary-directory*의 호출 지점에 대한 소스 위치 정보가 있으면 generated가 그 정보를 통합합니다. 결과 경로는 make-temporary-file처럼 base-dir와 결합됩니다.
base 패키지 버전 8.4.0.3에서 추가됨.
procedure
(call-with-atomic-output-file file proc
[ #:security-guard security-guard
#:rename-fail-handler rename-fail-handler ]) → any
file : path-string?
proc : (output-port? path? . -> . any)
security-guard : (or/c #f security-guard?) = #f
rename-fail-handler : (or/c #f (exn:fail:filesystem? path? . -> . any)) = #f
file과 같은 디렉토리에 쓰기용 임시 파일을 열고, proc을 호출해 임시 파일에 쓰고, 그다음 (Windows를 제외하고) 원자적으로 임시 파일을 file 자리에 옮겨요. 이동은 Unix와 Mac OS에서 단순히 rename-file-or-directory를 사용하고, rename-fail-handler가 제공되면 Windows에서도 rename-file-or-directory를 사용합니다. 그 외에는 Windows에서 이동이 추가 이름 바꾸기 단계(아래 참고)를 사용해 file의 동시 읽기로 인한 문제를 피합니다.
proc 함수는 임시 파일의 출력 포트와 임시 파일의 경로를 더해 호출됩니다. proc의 결과가 call-with-atomic-output-file의 결과입니다.
call-with-atomic-output-file 함수는 예외 시 임시 파일을 삭제하도록 마련합니다.
Windows는 프로그램이 열려 있는 파일을 삭제하거나 교체하는 것을 막지만, 열려 있는 파일의 이름 바꾸기는 허용합니다. 따라서 Windows에서 call-with-atomic-output-file은 기본적으로 두 번째 임시 파일 extra-tmp-file을 만들고, file을 extra-tmp-file로 이름을 바꾸고, proc이 쓴 임시 파일을 file로 이름을 바꾸고, 마지막으로 extra-tmp-file을 삭제합니다. 그 과정은 원자적이지 않으므로, rename-fail-handler가 제공되면 rename-file-or-directory가 사용됩니다. 이때 이동의 소스와 대상이 같은 디렉토리에 있으므로 rename-file-or-directory가 원자적일 가능성이 있습니다. 파일 이름을 바꾸는 동안 발생하는 파일 시스템 예외는 rename-fail-handler로 보내지며, 그것은 예외를 다시 던지거나 단순히 반환해 어쩌면 잠시 후에 다시 시도할 수 있습니다. 파일 시스템 예외 외에도 rename-fail-handler 프로시저는 path로 옮겨질 임시 파일 경로도 받습니다. rename-fail-handler 인자는 Windows에서만 사용됩니다.
base 패키지 버전 7.1.0.6에서 변경됨: #:rename-fail-handler 인자 추가.
procedure
(get-preference name [ failure-thunk flush-mode filename
#:use-lock? use-lock? #:timeout-lock-there timeout-lock-there
#:lock-there lock-there ]) → any
name : symbol?
failure-thunk : (-> any) = (lambda () #f)
flush-mode : any/c = 'timestamp
filename : (or/c path-string? #f) = #f
use-lock? : any/c = #t
timeout-lock-there : (or/c (path? . -> . any) #f) = #f
lock-there :
(or/c (path? . -> . any) #f)
= (make-handle-get-preference-locked
0.01 name failure-thunk flush-mode filename
#:lock-there timeout-lock-there)
(find-system-path 'pref-file)이 지정하는 파일, 또는 제공되고 #f가 아닌 filename에서 환경설정 값을 추출해요. 전자의 경우 환경설정 파일이 존재하지 않으면 get-preference는 이전 환경설정 파일을 읽으려 시도하고, 그다음 설정 디렉토리(가 find-config-dir로 보고하는) 안의 "racket-prefs.rktd" 파일을 읽으려 시도합니다. 그 파일들 중 아무것도 존재하지 않으면 환경설정 집합은 비어 있습니다.
환경설정 파일은 기본 파라미터 설정으로 쓰여진 심볼–값 리스트를 담아야 합니다. 어떤 대소문자에서든 racket:, mzscheme:, mred:, plt:로 시작하는 키는 Racket 구현자용으로 예약되어 있습니다. 환경설정 파일이 심볼–값 리스트를 담고 있지 않으면 log-error로 오류가 기록되고 failure-thunk가 호출됩니다.
get-preference의 결과는 name이 연관 리스트에 존재한다면 그와 연관된 값이고, 그 외에는 failure-thunk를 호출한 결과입니다.
환경설정 세팅은 (path->complete-path filename)을 캐시 키로 사용해 get-preference 호출들 사이에 (약하게) 캐시됩니다. flush-mode가 #f로 제공되면 파일을 다시 참고하는 대신 캐시가 사용됩니다. flush-mode가 'timestamp(기본값)로 제공되면 파일이 마지막으로 읽힌 시간과 같은 타임스탬프를 가질 때만 캐시가 사용됩니다. 그 외에는 파일이 다시 참고됩니다.
preferences-lock-file-mode가 'file-lock을 반환하는 플랫폼에서 use-lock?가 참이면 환경설정 파일 읽기는 잠금으로 보호됩니다. 여러 읽기자가 잠금을 공유할 수 있지만, 쓰기자는 잠금을 독점적으로 취합니다. 잠금을 사용할 수 없어 환경설정 파일을 읽을 수 없으면 lock-there가 잠금 파일의 경로로 호출됩니다. lock-there가 #f이면 예외가 던져집니다. 기본 lock-there 핸들러는 timeout-lock-there를 시도하기 전에 (각 시도 사이에 지연을 늘리며) 약 5번 재시도하며, 기본 timeout-lock-there는 예외를 일으킵니다.
put-preferences도 함께 보세요. 더 정교한 환경설정 시스템은 preferences:get을 보세요.
이전 환경설정 파일: filename이 제공되지 않아 (find-system-path 'pref-file)이 가리키는 파일이 존재하지 않을 때, 이전 Racket 버전과의 호환성을 위해 다음 경로가 검사됩니다:
- Windows:
(build-path (find-system-path 'pref-dir) 'up "PLT Scheme" "plt-prefs.ss") - Mac OS:
(build-path (find-system-path 'pref-dir) "org.plt-scheme.prefs.ss") - Unix:
(expand-user-path "~/.plt-scheme/plt-prefs.ss")
procedure
(put-preferences names vals [ locked-proc filename ]) → void?
names : (listof symbol?)
vals : list?
locked-proc : (or/c #f (path? . -> . any)) = #f
filename : (or/c #f path-string?) = #f
환경설정 값 집합을 설치하고 모든 현재 값을 (find-system-path 'pref-file)이 지정하는 환경설정 파일, 또는 제공되고 #f가 아닌 filename에 써요.
names 인자는 환경설정 이름을 제공하며, vals는 names와 같은 길이여야 합니다. vals의 각 요소는 write 출력이 읽을 수 있는 내장 데이터 타입의 인스턴스여야 합니다(즉 환경설정을 쓸 때 print-unreadable 파라미터가 #f로 설정됩니다).
현재 환경설정 값은 갱신하기 전에 환경설정 파일에서 읽히며, 쓰기 잠금은 파일 읽기 전부터 환경설정 파일이 갱신된 후까지 유지됩니다. 잠금은 환경설정 파일과 같은 디렉토리에 있는 파일의 존재로 구현됩니다. 자세한 내용은 preferences-lock-file-mode를 보세요. 환경설정 파일의 디렉토리가 아직 존재하지 않으면 생성됩니다.
쓰기 잠금이 이미 잡혀 있으면 locked-proc가 단일 인자 — 잠금 파일의 경로 — 로 호출됩니다. 기본 locked-proc(locked-proc 인자가 #f일 때 사용)는 오류를 보고합니다. 대안 thunk는 잠시 기다렸다가 다시 시도하거나, 사용자에게 잠금 파일을 삭제할 선택권을 줄 수 있습니다(이전 갱신 시도가 재앙을 만났고 잠금이 잠금 파일의 존재로 구현되는 경우).
filename이 #f이거나 제공되지 않고 환경설정 파일이 아직 존재하지 않으면, names에 언급되지 않은 환경설정에 대해 (있다면) "defaults" 컬렉션에서 읽은 값이 쓰여집니다.
procedure
(preferences-lock-file-mode) → (or/c 'exists 'file-lock)
현재 플랫폼에서 환경설정 파일 잠금을 구현하는 데 잠금 파일이 사용되는 방식을 보고해요.
'exists 모드는 현재 Windows를 제외한 모든 플랫폼에서 사용됩니다. 'exists 모드에서 잠금 파일의 존재는 쓰기 잠금이 잡혀 있음을 나타내며, 읽기자는 잠금이 필요 없습니다(환경설정 파일이 rename-file-or-directory로 원자적으로 갱신되기 때문).
'file-lock 모드는 현재 Windows에서 사용됩니다. 'file-lock 모드에서 잠금 파일에 대한 (port-try-file-lock?의 의미에서) 공유 및 배타 잠금이 환경설정 파일 내용에 대한 읽기자 및 쓰기자 잠금을 반영합니다. (환경설정 파일 자체는 잠기지 않습니다. 잠금이 rename-file-or-directory로 파일을 교체하는 것을 방해하기 때문입니다.)
procedure
(make-handle-get-preference-locked delay name [ failure-thunk flush-mode
filename #:lock-there lock-there #:max-delay max-delay ])
→ (path-string? . -> . any)
delay : real?
name : symbol?
failure-thunk : (-> any) = (lambda () #f)
flush-mode : any/c = 'timestamp
filename : (or/c path-string? #f) = #f
lock-there : (or/c (path? . -> . any) #f) = #f
max-delay : real? = 0.2
get-preference의 #:lock-there 인자로 사용하기에 적합한 프로시저를 만들어요. 여기서 name, failure-thunk, flush-mode, filename은 모두 결과 프로시저가 환경설정 조회를 재시도하기 위해 get-preference에 전달합니다.
get-preference를 호출하기 전에 결과 프로시저는 (sleep delay)를 사용해 일시 정지합니다. 그리고 (* 2 delay)가 max-delay보다 작으면 결과 프로시저는 make-handle-get-preference-locked를 호출해 get-preference에 전달할 새 재시도 프로시저를 생성하지만, delay는 (* 2 delay)로 합니다. (* 2 delay)가 max-delay보다 작지 않으면 대신 주어진 lock-there로 get-preference가 호출됩니다.
procedure
(call-with-file-lock/timeout filename kind thunk failure-thunk
[ #:lock-file lock-file #:delay delay #:max-delay max-delay ]) → any
filename : (or/c path-string? #f)
kind : (or/c 'shared 'exclusive)
thunk : (-> any)
failure-thunk : (-> any)
lock-file : (or/c #f path-string?) = #f
delay : (and/c real? (not/c negative?)) = 0.01
max-delay : (and/c real? (not/c negative?)) = 0.2
filename(또는 lock-file)에 대한 잠금을 얻은 다음 thunk를 호출해요. filename 인자는 lock-file이 #f일 때 잠금 파일 이름을 만들어 내는 데만 사용되는 파일 경로 접두사를 지정합니다. 구체적으로 lock-file이 #f일 때 call-with-file-lock/timeout은 make-lock-file-name을 사용해 잠금 파일 이름을 만듭니다. 잠금 파일이 아직 존재하지 않으면 생성됩니다. call-with-file-lock/timeout이 잠금 파일을 삭제하지는 않는다는 점에 주의하세요.
thunk가 반환하면 call-with-file-lock/timeout은 잠금을 해제하고 thunk의 결과를 반환합니다. call-with-file-lock/timeout 함수는 delay 초 후 재시도하고 delay가 max-delay에 도달할 때까지 지수 백오프로 계속 재시도합니다. call-with-file-lock/timeout이 잠금을 얻지 못하면 failure-thunk가 꼬리 위치에서 호출됩니다. kind 인자는 잠금이 port-try-file-lock?의 의미에서 'shared인지 'exclusive인지를 지정합니다.
예:
> (call-with-file-lock/timeout filename 'exclusive
(lambda () (printf "File is locked\n"))
(lambda () (printf "Failed to obtain lock for file\n")))
File is locked
> (call-with-file-lock/timeout #f 'exclusive
(lambda ()
(call-with-file-lock/timeout filename 'shared
(lambda () (printf "Shouldn't get here\n"))
(lambda () (printf "Failed to obtain lock for file\n"))))
(lambda () (printf "Shouldn't get here either\n"))
#:lock-file (make-lock-file-name filename))
Failed to obtain lock for file
procedure
(make-lock-file-name path) → path?
path : (or/c path-string? path-for-some-system?)
(make-lock-file-name dir name) → path?
dir : (or/c path-string? path-for-some-system?)
name : path-element?
경로의 파일 부분 앞에 Windows에서는(cross-system-type이 'windows를 보고할 때) "_LOCK"를, 다른 플랫폼에서는 ".LOCK"를 붙여 잠금 파일 이름을 만들어요.
예:
> (make-lock-file-name "/home/george/project/important-file")
#<path:/home/george/project/.LOCKimportant-file>
value
file-type-bits : #o170000
value
socket-type-bits : #o140000
value
symbolic-link-type-bits : #o120000
value
regular-file-type-bits : #o100000
value
block-device-type-bits : #o060000
value
directory-type-bits : #o040000
value
character-device-type-bits : #o020000
value
fifo-type-bits : #o010000
value
set-user-id-bit : #o004000
value
set-group-id-bit : #o002000
value
sticky-bit : #o001000
value
user-permission-bits : #o000700
value
user-read-bit : #o000400
value
user-write-bit : #o000200
value
user-execute-bit : #o000100
value
group-permission-bits : #o000070
value
group-read-bit : #o000040
value
group-write-bit : #o000020
value
group-execute-bit : #o000010
value
other-permission-bits : #o000007
value
other-read-bit : #o000004
value
other-write-bit : #o000002
value
other-execute-bit : #o000001
file-or-directory-permissions, file-or-directory-stat 및 그런 비트 연산과 함께 유용한 상수들이에요.