Dir 클래스
Dir 클래스
Dir 클래스의 객체는 기반 파일시스템의 디렉터리 하나를 나타내요. 크게 두 가지로 이뤄져 있어요:
- 객체를 만들 때 주어지는 문자열 path — 기반 파일시스템의 디렉터리를 가리켜요.
path메서드가 그 경로를 돌려줘요. - 문자열 *항목 이름(entry name)*들의 모음 — 각 항목은 기반 파일시스템의 디렉터리나 파일 이름이에요. 항목 이름은 배열처럼 또는 스트림처럼 방식으로 가져올 수 있어요.
예시에 대하여
이 페이지의 몇몇 예시는 이런 단순한 파일 트리를 써요:
example/
├── config.h
├── lib/
│ ├── song/
│ │ └── karaoke.rb
│ └── song.rb
└── main.rb
다른 예시들은 Ruby 프로젝트 자체의 파일 트리를 사용해요.
배열 같은 Dir
Dir 객체는 어떤 면에서 배열과 같아요:
- 인스턴스 메서드
children,each,each_child를 갖고 있어요. - 모듈
Enumerable을 include해요.
스트림 같은 Dir
Dir 객체는 어떤 면에서 스트림과 같아요.
스트림은 처음에 읽기용으로 열려 있지만, close 메서드로 수동으로 닫을 수 있고, Dir.open을 블록과 함께 호출해 만들었다면 블록 탈출 시 닫혀요. 닫힌 스트림은 더 이상 조작할 수 없고 다시 열 수도 없어요.
스트림은 *위치(position)*를 갖는데, 이는 디렉터리의 항목 인덱스예요:
- 초기 위치는 0 (첫 항목 앞).
tell(pos별칭) 메서드는 위치를 돌려줘요.pos=메서드는 위치를 설정하고(스트림 밖의 값은 무시) 위치를 돌려줘요.seek는pos=과 같지만self를 돌려줘요 (체이닝에 편리).read메서드는 스트림 끝이 아니면 다음 항목을 읽고 위치를 증가시키며, 스트림 끝이면 위치를 증가시키지 않아요.rewind메서드는 위치를 0으로 설정해요.
예시 (단순 파일 트리 사용):
dir = Dir.new('example') # => #<Dir:example>
dir.pos # => 0
dir.read # => "."
dir.read # => ".."
dir.read # => "config.h"
dir.read # => "lib"
dir.read # => "main.rb"
dir.pos # => 5
dir.read # => nil
dir.pos # => 5
dir.rewind # => #<Dir:example>
dir.pos # => 0
dir.pos = 3 # => 3
dir.pos # => 3
dir.seek(4) # => #<Dir:example>
dir.pos # => 4
dir.close # => nil
dir.read # Raises IOError.
여기 있는 것들 (What's Here)
먼저, 다른 곳에 있는 것들. Dir 클래스는:
Object클래스에서 상속받아요.- 수십 개의 추가 메서드를 제공하는 모듈
Enumerable을 include해요.
여기서 Dir 클래스는 다음 용도에 유용한 메서드들을 제공해요:
- 읽기(Reading)
- 설정(Setting)
- 조회(Querying)
- 반복(Iterating)
- 기타(Other)
읽기
close:self의 디렉터리 스트림을 닫아요.pos=:self의 디렉터리 스트림 위치를 설정해요.read:self의 디렉터리 스트림에서 다음 항목을 읽고 돌려줘요.rewind:self의 디렉터리 스트림 위치를 첫 항목으로 설정해요.seek:self의 디렉터리 스트림 위치를 주어진 오프셋의 항목으로 설정해요.
설정
::chdir: 현재 프로세스의 작업 디렉터리를 주어진 디렉터리로 바꿔요.::chroot: 현재 프로세스의 파일시스템 루트를 주어진 디렉터리로 바꿔요.
조회
::[]: 플래그를 넘길 수 없다는 점만 빼고::glob과 같아요.::children: 주어진 디렉터리의 자식(파일과 디렉터리 모두) 이름 배열을 돌려줘요..과..은 포함하지 않아요.::empty?: 주어진 경로가 빈 디렉터리인지 돌려줘요.::entries: 주어진 디렉터리의 자식 이름 배열을 돌려줘요..과..을 포함해요.::exist?: 주어진 경로가 디렉터리인지 돌려줘요.::getwd(pwd별칭): 현재 작업 디렉터리 경로를 돌려줘요.::glob: 주어진 패턴과 플래그에 일치하는 파일 경로 배열을 돌려줘요.::home: 주어진 사용자 또는 현재 사용자의 홈 디렉터리 경로를 돌려줘요.children:self의 자식 이름 배열..과..은 포함하지 않아요.fileno:self의 정수 파일 디스크립터를 돌려줘요.path(to_path별칭):self를 만드는 데 쓰인 경로를 돌려줘요.tell(pos별칭):self의 디렉터리 스트림의 정수 위치를 돌려줘요.
반복
::each_child: 주어진 디렉터리의 각 항목으로 주어진 블록을 호출해요..과..은 포함하지 않아요.::foreach: 주어진 디렉터리의 각 항목으로 주어진 블록을 호출해요..과..을 포함해요.each:self의 각 항목으로 주어진 블록을 호출해요..과..을 포함해요.each_child:self의 각 항목으로 주어진 블록을 호출해요..과..은 포함하지 않아요.
기타
::mkdir: 주어진 경로에 (선택 권한으로) 디렉터리를 만들어요.::new: 주어진 경로에 (선택 인코딩으로) 새Dir을 돌려줘요.::open:::new와 같지만, 블록을 주면 블록에Dir을 넘겨 블록 탈출 시 닫아요.::unlink(::delete,::rmdir별칭): 주어진 디렉터리를 제거해요.inspect:self의 문자열 설명을 돌려줘요.
클래스 메서드
-
Dir[*patterns, base: nil, sort: true] → array— 인자patterns와 키워드 인자base·sort의 값으로Dir.glob을 호출하고, 선택된 항목 이름 배열을 돌려줘요. -
chdir(new_dirpath) → 0— 현재 작업 디렉터리를 바꿔요.인자
new_dirpath와 블록 없이: 주어진dirpath로 변경:Dir.pwd # => "/example" Dir.chdir('..') # => 0 Dir.pwd # => "/"인자도 블록도 없이:
HOME환경 변수 값으로 변경, 정의돼 있으면; 아니면LOGDIR환경 변수 값으로; 아니면 변경하지 않아요.인자
new_dirpath와 블록과 함께: 작업 디렉터리를 임시로 변경해요. 블록을 인자와 함께 호출하고, 주어진 디렉터리로 변경하고, 블록을 실행하고(새 경로 넘김), 이전 작업 디렉터리를 복원하고, 블록의 반환값을 돌려줘요.Dir.chdir('/var/spool/mail') Dir.pwd # => "/var/spool/mail" Dir.chdir('/tmp') do Dir.pwd # => "/tmp" end Dir.pwd # => "/var/spool/mail"블록 있는
Dir.chdir호출은 중첩할 수 있어요. 멀티스레드 프로그램에서 다른 스레드가 하나 열고 있는 동안 또 다른 스레드가chdir블록을 열려고 하면, 또는chdir에 넘긴 블록 안에서 블록 없는chdir호출이 일어나면 오류가 발생해요. 대상 디렉터리가 없으면 예외를 던져요. -
children(dirpath) → array—dirpath의 디렉터리에 있는 항목 이름 배열을 돌려줘요 ('.'과'..'제외). 각 항목에 주어진 인코딩을 설정해요.Dir.children('/example') # => ["config.h", "lib", "main.rb"] -
chroot(dirpath) → 0— 호출 프로세스의 루트 디렉터리를dirpath로 변경해요. 새 루트 디렉터리는'/'로 시작하는 경로명에 쓰여요. 루트 디렉터리는 호출 프로세스의 모든 자식이 상속해요. 권한 있는 프로세스만chroot를 호출할 수 있어요. -
rmdir(dirpath) → 0— 기반 파일시스템에서dirpath의 디렉터리를 제거해요. 디렉터리가 비어 있지 않으면 예외.Dir.rmdir('foo') # => 0 -
each_child(dirpath) {|entry_name| ... } → nil—Dir.foreach와 같지만'.'과'..'항목이 포함되지 않아요. -
empty?(dirpath) → true or false—dirpath가 빈 디렉터리를 가리키는지 돌려줘요.dirpath = '/tmp/foo' Dir.mkdir(dirpath) Dir.empty?(dirpath) # => true Dir.empty?('/example') # => false -
entries(dirname, encoding: 'UTF-8') → array—dirpath디렉터리의 항목 이름 배열을 돌려줘요. 각 항목에 주어진 인코딩을 설정해요.Dir.entries('/example') # => ["config.h", "lib", "main.rb", "..", "."] -
exist?(dirpath) → true or false—dirpath가 기반 파일시스템의 디렉터리인지 돌려줘요.File.directory?와 같아요.Dir.exist?('/example') # => true Dir.exist?('/nosuch') # => false -
fchdir(fd) → 0— 현재 작업 디렉터리를 정수 파일 디스크립터fd로 지정된 디렉터리로 변경해요. UNIX 소켓이나 자식 프로세스로 파일 디스크립터를 넘길 때chdir대신fchdir을 쓰면 time-of-check-time-of-use 취약점을 피할 수 있어요. 블록과 함께: 작업 디렉터리를 임시로 변경해요. 이 메서드는 POSIX 2008의 fchdir() 함수를 사용하며, 비-POSIX 플랫폼에서는 구현되지 않아요 (NotImplementedError발생). -
for_fd(fd) → dir— 주어진 정수 디렉터리 파일 디스크립터fd로 지정된 디렉터리를 나타내는 새Dir객체를 돌려줘요. 돌려받은d1은 연관된 경로가 없어요 (d1.path # => nil). fdopendir() 함수를 사용하며 비-POSIX 플랫폼에서는 미구현. -
foreach(dirpath, encoding: 'UTF-8') {|entry_name| ... } → nil—dirpath디렉터리의 각 항목 이름으로 블록을 호출해요. 각entry_name에 주어진 인코딩을 설정해요. 블록이 없으면 enumerator를 돌려줘요. -
pwd → string— 현재 작업 디렉터리 경로를 돌려줘요:Dir.pwd # => "/tmp" -
glob(patterns, flags: 0, base: nil, sort: true) → array— 인자로 선택된 항목 이름 entry_names의 배열을 구성해요. 인자patterns는 문자열 패턴 또는 문자열 패턴 배열이에요 (정규식이 아니라는 점 유의). 블록 없이 배열 entry_names를 돌려주고, 블록과 함께 각 항목 이름으로 블록을 호출하고nil을 돌려줘요.키워드 인자
base가 주어지면 그 값이 베이스 디렉터리를 지정해요. 각 패턴 문자열은 베이스 디렉터리 기준의 항목을 지정해요. 기본값은'.'이고, 결과의 항목 이름에는 베이스 디렉터리가 앞에 붙지 않아요. 키워드sort의 값이 정렬 여부를 지정해요. 기본값은true,false를 넘기면 정렬을 끄지만 기반 파일시스템이 이미 정렬했을 수도 있어요.패턴(Patterns): 각 패턴 문자열은 특정 메타문자에 따라 확장돼요:
'*': 항목 이름의 어떤 부분 문자열과도 일치 (regexp/.*/mx와 비슷). 앞뒤 문자로 제한될 수 있음. Unix 숨김 항목명("dot file")은 일치하지 않아요. 포함하려면IO::FNM_DOTMATCH플래그나'{*,.*}'같은 걸 써요.'**': 슬래시'/'가 뒤따르면 재귀적으로 항목 이름과 일치. 다른 문자가 포함됐거나 슬래시가 뒤따르지 않으면'*'와 동등.'?': 단일 문자와 일치 (regexp/./와 비슷).'[*set*]': 문자열 set의 한 문자와 일치. Regexp 문자 클래스처럼 동작 (부정'[^a-z]'포함).'{*abc*,*xyz*}': 문자열 abc 또는 xyz와 일치. Regexp 교체(alternation)처럼 동작. 두 개 이상의 대안도 가능.\: 뒤따르는 메타문자를 이스케이프. Windows에서는 문자열 패턴에 백슬래시를 못 쓸 수 있어요 (Dir['c:\foo*']는 안 되고Dir['c:/foo*']를 쓰세요).
예시 (단순 파일 트리 사용):
File.basename(Dir.pwd) # => "example" Dir.glob('config.?') # => ["config.h"] Dir.glob('*.[a-z][a-z]') # => ["main.rb"] Dir.glob('*.{rb,h}') # => ["main.rb", "config.h"] Dir.glob('*') # => ["config.h", "lib", "main.rb"] Dir.glob('*', File::FNM_DOTMATCH) # => [".", "config.h", "lib", "main.rb"] Dir.glob(["*.rb", "*.h"]) # => ["main.rb", "config.h"] Dir.glob('**/*.rb') => ["lib/song/karaoke.rb", "lib/song.rb", "main.rb"]플래그(Flags): 키워드 인자
flags가 주어지면(기본값은 0), 그 값은 모듈File::Constants에 정의된 상수 중 하나 이상의 비트 OR이어야 해요. 적용되는 플래그:File::FNM_DOTMATCH:'.'로 시작하는 항목 이름이 매칭에 고려되도록 지정.File::FNM_EXTGLOB: 패턴 확장'{*a*,*b*}'를 활성화 (regexp union처럼 동작).File::FNM_NOESCAPE: 백슬래시'\'이스케이프 비활성화.File::FNM_PATHNAME:'*'와'?'메타문자가 디렉터리 구분자와 일치하지 않도록 지정.File::FNM_SHORTNAME: 패턴이 존재한다면 짧은 이름과 일치할 수 있도록 지정. Windows 전용.
-
home(user_name = nil) → dirpath—user_name이nil이 아니면 그 사용자의, 아니면 현재 로그인 사용자의 홈 디렉터리 경로를 돌려줘요:Dir.home # => "/home/me",Dir.home('root') # => "/root".user_name이 사용자 이름이 아니면ArgumentError. -
mkdir(dirpath, permissions = 0775) → 0— 기반 파일시스템의dirpath에 주어진permissions로 디렉터리를 만들어요.permissions인자는 Windows에서 무시돼요.Dir.mktmpdir(require 'tmpdir')는 임시 디렉터리를 만들어요. -
new(dirpath) → dir—dirpath디렉터리에 대한 새Dir객체를 돌려줘요. 선택 키워드 인자encoding은 디렉터리 항목 이름의 인코딩을 지정해요.nil(기본값)이면 파일시스템의 인코딩을 써요.Dir.new('.') # => #<Dir:.> -
open(dirpath) → dir—dirpath디렉터리에 대한 새Dir객체를 만들어요. 블록 없이:Dir.new(dirpath, encoding)과 동등. 블록과 함께: 만들어진dir로 블록을 호출하고, 블록 탈출 시dir을 닫고 블록의 값을 돌려줘요.Dir.open('.') {|dir| dir.inspect } # => "#<Dir:.>" -
pwd → string— 현재 작업 디렉터리 경로:Dir.chdir("/tmp") # => 0,Dir.pwd # => "/tmp" -
rmdir(dirpath) → 0—dirpath의 디렉터리를 제거해요. 비어 있지 않으면 예외. -
tmpdir— 운영체제의 임시 파일 경로를 돌려줘요:require 'tmpdir'; Dir.tmpdir # => "/tmp"
인스턴스 메서드
-
chdir → 0— 현재 작업 디렉터리를self로 변경해요. 블록과 함께: 임시로 변경. 가능하면Dir.fchdir, 아니면Dir.chdir을 사용해요. -
children → array—self의 항목 이름 배열.'.'과'..'제외:Dir.new('/example').children # => ["config.h", "lib", "main.rb"] -
close → nil—self의 스트림이 열려 있으면 닫고nil을 돌려줘요. 이미 닫혀 있으면 무시. -
each {|entry_name| ... } → self—self의 각 항목 이름으로 블록을 호출해요 (.·..포함). 블록이 없으면Enumerator. -
each_child {|entry_name| ... } → self—self의 각 항목 이름으로 블록을 호출해요 ('.'·'..'제외). 블록이 없으면 enumerator. -
fileno → integer— dir에 쓰인 파일 디스크립터를 돌려줘요:d.fileno # => 8. dirfd() 함수 사용. 비-POSIX 플랫폼 미구현. -
inspect → string—self의 문자열 설명:Dir.new('example').inspect # => "#<Dir:example>" -
path → string or nil—self를 만드는 데 쓰인dirpath문자열 (또는Dir.for_fd로 만들었다면nil):Dir.new('example').path # => "example" -
pos = position → integer—self의 위치를 설정하고position을 돌려줘요.position은 이전tell호출에서 돌려받은 값이어야 해요. -
read → string or nil—self에서 다음 항목 이름을 읽고 돌려줘요. 스트림 끝이면nil. -
rewind → self—self의 위치를 0으로 설정해요. -
seek(position) → self—self의 위치를 설정하고self를 돌려줘요. -
tell → integer—self의 현재 위치를 돌려줘요.