2.2 파일 및 디렉토리 다루기 Last updated: 2023-10-31 18:35:41

파일을 열어서 읽고 쓰는 것 뿐만 아니라 파일과 디렉토리를 처리하기 위해 필요한 여러가지 유용한 기능들에 대해서 알아보자.

2.2.1 파일 존재 여부 확인

지정한 이름의 파일이 실제로 존재하는지 확인하려면 표준 모듈인 os를 이용해야 한다. 다음은 파일이 존재하는지 확인하는 방법에 대한 기본 형식이다. os.path.exists( )는 파일이 존재하는지 검사하는 함수이다.

형식

os.path.exists(path)

파라미터

• path : 존재 여부를 검사할 파일 전체 경로를 입력한다.

반환

(bool) 파일이 존재하면 True, 그렇지 않으면 False이다.

파일이 존재하는지 확인하는 예제이다.


[예제 6- 40] 파일 존재 확인하기

import os

if os.path.exists("prologue.txt"):
    print("file exists")
else:
    print("file does not exists")

[결과]

file exists


2.2.2 파일 삭제

지정한 파일을 삭제하는 함수에 대해 알아보자. 단, 파일을 삭제할 때는 실행하는 프로그램이나 로그인 계정에서 파일을 삭제할 수 있는 권한이 있어야 하고, 파일이 다른 프로그램에 의해 열려 있으면 삭제에 실패한다. os.remove( )는 파일을 삭제하는 함수이다. 형식은 다음과 같다.

형식

os.remove(path)

파라미터

• path : 삭제할 파일 전체 경로를 입력한다.

다음은 파일을 삭제하는 예제이다.


[예제 6- 41] 파일 삭제하기

import os

# [1] 파일 경로
file_path = 'prologue.txt'

# [2] 삭제 전에 파일 존재 여부 확인
if os.path.exists(file_path):
    # [3] 파일 삭제
    os.remove(file_path)
    print(file_path, 'file deleted')

[결과]

prologue.txt file deleted

위 예제에 대해 설명한다.

  • [1]에서 삭제할 파일 경로를 변수 file_path에 지정했다. 만일 실행하는 프로그램과 다른 경로에 삭제할 파일이 존재한다면, 전체 경로 혹은 상대 경로를 포함해 파일명을 지정하시기 바란다.

  • [2]에서 삭제할 파일이 존재하는지 검사한다. 파일이 존재하지 않는데 os.remove( ) 함수를 이용해 파일을 삭제하면 FileNotFoundError 오류가 발생한다.

  • [3]에서 os.remove( ) 함수를 이용해 파일을 삭제 했다.

  • 정상적으로 파일이 삭제되었으므로 오류가 발생되지 않고 결과가 출력 되었다.

만일 존재하지 않는 파일을 삭제하려고 하면 다음과 같이 FileNotFoundError 오류가 발생된다. 그러므로 파일 삭제 전에는 os.path.exists( ) 함수를 이용해 파일 존재 여부를 먼저 검사할 것을 추천한다.


[결과]

FileNotFoundError: [WinError 2] 지정된 파일을 찾을 수 없습니다: 'prologue.txt'


2.2.3 디렉토리 삭제

디렉토리를 삭제하는 방법에 대해 알아보자. 단, 디렉토리가 비어 있어야 오류 없이 디렉토리 삭제가 가능하다. 디렉토리 내에 다른 디렉토리나 파일이 존재하는 경우에는 먼저 해당 파일과 디렉토리를 삭제해야 한다. 디렉토리를 삭제하는 함수는 다음과 같다.

형식

os.rmdir(path)

파라미터

• path : 삭제할 디렉토리명을 입력한다.

디렉토리를 삭제하는 예제는 다음과 같다. os 모듈을 먼저 import 하고 함수를 사용해야 한다.


[예제 6- 42] 디렉토리 삭제하기

import os
os.rmdir("poet")

[결과]

OSError: [WinError 145] 디렉터리가 비어 있지 않습니다: 'poet'

파일이 존재해 비어 있지 않은 디렉토리를 삭제하려고 하면 다음과 같이 OSError 오류가 발생된다.



2.2.4 디렉토리 생성

디렉토리를 생성하는데 자주 사용하는 함수는 os.mkdir( )과 os.mkdirs( ) 이다. 두 함수는 약간의 차이가 있기 때문에 다음의 설명을 확인하고 사용하시기 바란다.

형식

os.mkdir(path)

파라미터

• path : 생성할 디렉토리명을 입력한다.

먼저 os.mkdir( )는 디렉토리를 생성하는 기본적인 함수이다. path에 생성할 디렉토리 이름과 경로를 지정하면 해당 위치에 디렉토리를 생성한다. path에 입력하는 경로는 절대 경로이거나 상대 경로이거나 상관 없다. 디렉토리를 생성하는 예제를 확인해보자.


[예제 6- 43] 폴더 생성하기

import os

# [1] 절대 경로의 디렉토리 생성
os.mkdir('d:	est_folder1')

# [2] 상대 경로의 디렉토리 생성
os.mkdir('.	est_folder2')

위 예제에 대해 설명한다.

  • [1]에서 절대 경로를 지정하고 test_folder1 이라는 디렉토리를 생성한다.

  • [2]에서 상대경로, 즉 상위 디렉토리로 이동해 test_folder2라는 이름의 디렉토리를 생성한다.

단, 디렉토리를 생성할 때는 기존에 동일한 이름의 디렉토리가 존재하지 않아야 한다. 만일 이미 동일한 이름의 디렉토리가 존재한다면 다음과 같이 FileExistsError 오류가 발생된다.


[결과]

FileExistsError: [WinError 183] 파일이 이미 있으므로 만들 수 없습니다: 
'.\test_folder2'


2.2.5 디렉토리 내용 조회

지정한 디렉토리 위치에 존재하는 모든 파일 및 디렉토리 목록을 조회하는데 os.listdir( ) 함수를 사용한다.

형식

os.listdir(path)

파라미터

• path : 조회할 디렉토리 경로. 지정하지 않을 경우 현재 위치에서 실행된다.

반환

(list) 파일 및 디렉토리 명칭 리스트가 반환된다.

[예제 6- 44] 디렉토리 내 항목 조회하기

import os

# [1] 현재 디렉토리의 파일 목록 조회
dir_all_items = os.listdir()

# [2] 반환된 결과의 타입 출력
print('type:', type(dir_all_items))

# [3] 파일 목록 출력
dir_all_items

[결과]

type: <class 'list'>
['basket',
 'fruit.py',
 'poet',
 'prologue1.txt',
 'prologue_euckr.txt',
 'prologue_jp.txt',
 'prologue_utf8.txt']

위 예제에 대해 설명한다.

  • [1]에서 현재 디렉토리의 파일 목록을 조회한다. 반환되는 결과에는 존재하는 파일 이름과 디렉토리 이름이 리스트 형태로 반환된다.

  • [2] 반환된 변수의 타입을 출력해보면 <class 'list'>이다. 파일 혹은 디렉토리 이름의 리스트이다.

  • [3]에서 리스트 변수를 출력한다.

  • 출력 결과를 보면 파일 혹은 디렉토리 이름이 섞여서 알파벳 오름차순으로 출력되었다.


A. 디렉토리의 파일 목록 조회

앞에서 설명한 os.listdir( ) 함수를 통해 디렉토리 내의 내용을 조회하면 파일과 디렉토리가 함께 결과로 조회된다. 디렉토리는 제외하고 파일의 목록만을 조회하고 싶은 경우 os.path.isdir( ) 혹은 os.path.isfile( ) 함수를 이용해 파일을 찾아낼 수 있다. 다음은 os.path.isdir( ) 함수를 이용해 디렉토리를 걸러내는 예제이다.

[예제 6- 45] 디렉토리 내 파일 목록 조회하기

import os

# [1] 현재 디렉토리의 파일 목록 조회
dir_all_items = os.listdir()

# [2] 파일 목록 for 반복문
for item in dir_all_items:
    
    # [3] 디렉토리 여부 검사
    if os.path.isdir(item):
        pass
    else:
        # [4] 파일인 경우 출력
        print(item)

[결과]

fruit.py
prologue1.txt
prologue_euckr.txt
prologue_jp.txt
prologue_utf8.txt

위 예제에 대해 설명한다.

  • [1]에서 디렉토리 내의 내용을 모두 조회한다.

  • [2]에서 각 항목에 대해 for 반복문을 실행한다.

  • [3]에서 os.path.isdir( ) 함수를 이용해 현재 선택된 항목이 디렉토리인지 검사한다. 반대로 os.path.isfile( ) 함수를 통해 파일인지 검사할 수도 있다.

  • [4]에서 파일 이름을 출력한다.


B. 디렉토리 경로의 파일 목록 조회

디렉토리의 파일 목록을 조회하는 방법에 대해 알아보자. os.listdir( ) 함수에 인자로 조회할 디렉토리의 경로를 지정한다.

[예제 6- 46] 지정한 경로 내에 파일 목록 조회하기

import os

# [1] 디렉토리 경로
dir_loc = 'D:	est_folder1'

# [2] 디렉토리의 파일 목록 조회
dir_all_items = os.listdir(dir_loc)

# [3] 파일 목록 for 반복문
for item in dir_all_items:
    
    item_path = os.path.join(dir_loc, item)
    # [4] 디렉토리 여부 검사
    if os.path.isdir(item_path):
        pass
    else:
        # [5] 파일인 경우 출력
        print(item_path)

[결과]

D:\test_folder1\apple.bmp
D:\test_folder1\apple.txt
D:\test_folder1\banana.jpg
D:\test_folder1\banana.txt
D:\test_folder1\orange.png
D:\test_folder1\orange.txt

위 예제에 대해 설명한다.

  • [1]에서 디렉토리 내의 내용을 모두 조회한다.

  • [2]에서 각 항목에 대해 for 반복문을 실행한다.

  • [3]에서 os.path.isdir( ) 함수를 이용해 현재 선택된 항목이 디렉토리인지 검사한다. 반대로 os.path.isfile( ) 함수를 통해 파일인지 검사할 수도 있다.

  • [4]에서 파일 이름을 출력한다.

Hint! 파이썬에서 경로 구분자 os.sep

파이썬에서 문자열로 파일 및 디렉토리의 위치를 표현할 때 드라이브, 디렉토리, 파일명 등을 잇는 특수 기호는 os.sep 이다. 윈도우에서 os.sep를 출력해보면 이중 역슬레시 "\\"를 출력한다. 한 번에 전체 경로를 표현하려면 "c:\\fruit\\apple.png"와 같이 사이사이에 경로 구분자를 직접 써 주어야 한다. 경로 구분자는 운영체제별로 다를 수 있는데 이러한 불편함을 해결하기 위해 파이썬이 제공하는 함수는 os.path.join( ) 이다. 이 함수에 각 드라이브명, 디렉토리명, 파일명 등을 인자로 넘기면 파이선이 알아서 연결된 전체 경로의 문자열을 반환해 준다.

filepath = os.path.join('c:\\', 'fruit','apple.png')
print(filepath)

# 결과
'c:\\fruit\\apple.png'



C. 컴프리헨션을 이용해 파일 목록 필터링

컴프리헨션을 이용하면 좀더 간단하게 파일의 대상만 필터링하여 파일 이름만의 리스트를 만들 수 있다.

형식

[x for x in all_list if os.path.isfile(x)]

파라미터

• all_list : os.listdir( )에서 반환된 디렉토리 내 전체 내용 리스트

반환

(list) 파일 이름에 해당하는 리스트가 반환된다.

다음은 컴프리헨션을 사용해 파일명만 필터링하여 리스트를 생성하는 예제이다.


[예제 6- 47] 컴프리헨션으로 파일 목록 리스트 만들기

import os

# [1] 현재 디렉토리의 파일 목록 조회
dir_all_items = os.listdir()

# [2] 파일 목록 필터링
dir_file_items = [x for x in dir_all_items if os.path.isfile(x)]

# [3] 결과 출력
dir_file_items

[결과]

['fruit.py',
 'prologue1.txt',
 'prologue_euckr.txt',
 'prologue_jp.txt',
 'prologue_utf8.txt']

위 예제에 대해 설명한다.

  • [1]에서 디렉토리 내에 존재하는 모든 항목을 조회한다.

  • [2]에서 리스트 컴프리헨션을 이용해 for 문을 실행하고 if 조건에서 os.path.isfile( ) 함수로 파일인지 여부를 판단하여 생성한 리스트를 dir_file_items 변수에 할당한다.

  • [3]에서 리스트 결과를 출력한다.

  • 결과를 보면 디렉토리는 제거되고 파일 목록만 출력되었다.


D. 디렉토리의 확장자 파일 목록 조회

디렉토리 내의 파일 중에서 특정 확장자에 해당하는 파일 목록을 조회하는 방법에 대해 설명한다. 앞에서 사용한 os.listdir( ) 함수를 이용해 전체 목록을 조회하고, os.path.isfile( ) 함수를 이용해 파일인지 확인한다. 그리고 os.path.splitext( ) 함수를 이용해 파일의 이름과 확장자명을 분리하여 검사한다.

형식

root, ext = os.path.splitext(path)

파라미터

• path : 파일 명칭 및 전체 경로명을 전달한다.

반환

• root(string) : 파일 이름에서 확장자를 제외한 명칭으로 path 변수에 경로가 포함된 경우 경로를 포함한 이름이 반환된다.
• ext (string) : 파일명에서 .을 포함한 확장자가 반한된다.

디렉토리 내에서 .txt 확장자만 갖는 파일 리스트를 조회하는 예제를 살펴보자.


[예제 6- 48] txt 확장자의 파일 목록 조회하기

import os

# [1] 디렉토리 경로
dir_loc = 'D:\\test_folder1'

# [2] 디렉토리의 파일 목록 조회
dir_all_items = os.listdir(dir_loc)

# [3] 파일 목록 for 반복문
for item in dir_all_items:
    
    item_path = os.path.join(dir_loc, item)
    # [4] 디렉토리 여부 검사
    if os.path.isdir(item_path):
        pass
    else:
        root, ext = os.path.splitext(item_path)
        # [5] 파일인 경우 출력
        print(root, "=>", ext)

[결과]

D:\test_folder1\apple => .bmp
D:\test_folder1\apple => .txt
D:\test_folder1\banana => .jpg
D:\test_folder1\banana => .txt
D:\test_folder1\orange => .png
D:\test_folder1\orange => .txt


E. 텍스트 형식의 파일 목록 조회하기

다음은 ‘.txt’의 확장를 갖는 파일만 리스트로 생성하는 예제이다.

[예제 6- 49] txt 확장자 파일 리스트로 만들기

import os

# [1] 디렉토리 경로
dir_loc = 'D:	est_folder1'

# [2] 디렉토리의 파일 목록 조회
dir_all_items = os.listdir(dir_loc)
dir_txt_items = []

# [3] 파일 목록 for 반복문
for item in dir_all_items:
    
    item_path = os.path.join(dir_loc, item)
    # [4] 디렉토리 여부 검사
    if os.path.isdir(item_path):
        continue
    else:
        # [5] 파일의 경로와 확장자를 분리
        root, ext = os.path.splitext(item_path)
        
        # [6] 파일의 확장자를 검사
        if ext == ".txt":
            dir_txt_items.append(item_path)
            
print(dir_txt_items)

[결과]

['D:\test_folder1\apple.txt',
 'D:\test_folder1\banana.txt',
 'D:\test_folder1\orange.txt']

위 예제에 대해 설명한다.

  • [1]에서 디렉토리 경로를 지정한다.

  • [2]에서 디렉토리 내에 포함된 전체 항목을 조회한다. 그리고 ‘.txt’ 확장자를 갖는 파일 목록의 결과를 저장하기 위해 리스트 변수를 생성한다.

  • [3]에서 디렉토리 항목 전체에 대해 for 문을 반복한다.

  • [4]에서 항목이 디렉토리인 경우 다음으로 넘어간다.

  • [5]에서 파일 경로에서 확장자를 분리한다.

  • [6]에서 확장자가 ‘.txt’인 경우 dir_txt_items 변수에 추가한다.

  • 출력 결과를 보면 ‘.txt’ 확장자를 갖는 파일 목록만 출력되었다.

Hint! 확장자는 대소문자를 구분하나?

os.path.splitext( ) 함수를 이용해 확장자를 분리하면 확장자 문자열을 원하는 문자열과 비교할 수 있다. 하지만, 때에 따라 파일 확장자가 소문자와 대문자가 섞여 있을 수 있다.

os.path.splitext( ) 함수는 대소문자를 구분하여 문자열을 반환한다. 따라서 반환 된 문자열을 비교하려면 소문자와 대문자를 따로 검사해야 한다.

다음과 같이 문자열을 lower( ) 함수를 이용해 소문자로 변경하여 검사하면 이러한 문제를 해결할 수 있다.

if ext.lower( ) == ".txt":
    dir_txt_items.append(item_path)



F. 이미지 형식의 파일 목록 조회하기

폴더 내에서 이미지 포맷의 파일만 골라 리스트 변수에 담으려고 하면 다음과 같이 확장자 검사 로직을 적용한다.

[예제 6- 50] 이미지 파일 목록 조회하기

import os

# [1] 디렉토리 경로
dir_loc = 'D:\\test_folder1'

# [2] 디렉토리의 파일 목록 조회
dir_all_items = os.listdir(dir_loc)
dir_txt_items = []

# [3] 파일 목록 for 반복문
for item in dir_all_items:
    
    item_path = os.path.join(dir_loc, item)
    # [4] 디렉토리 여부 검사
    if os.path.isdir(item_path):
        continue
    else:
        # [5] 파일의 경로와 확장자를 분리
        root, ext = os.path.splitext(item_path)
        
        # [6] 파일의 확장자를 검사
        if ext.lower() in ['.bmp', '.gif', '.tif', '.jpg', '.jpeg', '.png' ]:
            dir_txt_items.append(item_path)
            
print(dir_txt_items)

[결과]

['D:\test_folder1\apple.bmp',
 'D:\test_folder1\banana.jpg',
 'D:\test_folder1\orange.png']

위 예제에 대해 설명한다.

  • 나머지는 동일하고 [6]에서 확장자를 검사하는 로직을 수정했다. 확장자를 소문자로 변경한 후 in 키워드를 이용해 이미지 확장자를 포함한 리스트에 현재의 확장자가 포함되는지 검사한다.

  • 결과를 보면 이미지 파일 형식만 출력되었다.