[CORE-005][기초] 파일·폴더·경로와 확장자 한 번에 이해하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[CORE-005][기초] 파일·폴더·경로와 확장자 한 번에 이해하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 241회 작성일 26-08-31 19:37

본문

[이번 수업]
파일과 폴더의 관계, 상대·절대 경로, 파일명과 확장자를 구분합니다.

[선수지식]
CORE-001~004의 컴퓨터·운영체제·터미널 기초와 Python 실행 방법이 필요합니다. 실습은 현재 폴더 아래 `path_lab`만 사용합니다.

[학습목표]
1. 파일, 폴더, 경로의 역할을 설명한다.
2. 상대 경로와 절대 경로를 구분한다.
3. name, stem, suffix, suffixes를 올바르게 읽는다.

[핵심개념]
파일은 이름을 가진 데이터 묶음이고, 폴더(디렉터리)는 파일과 다른 폴더의 이름을 정리합니다. `docs/guide.txt`처럼 현재 작업 폴더를 기준으로 해석하는 주소가 상대 경로이고, 루트나 드라이브부터 모두 적은 주소가 절대 경로입니다. `Path(...).resolve()`는 절대 경로를 만들고 `..`와 심볼릭 링크를 정리합니다.

Windows는 보통 역슬래시와 드라이브 문자를, macOS·Linux는 슬래시와 루트를 사용합니다. 코드에 구분자를 직접 연결하면 이식성이 떨어집니다. `Path('path_lab') / 'notes.txt'`처럼 `/` 연산자로 경로 조각을 결합하면 실행 중인 운영체제 규칙에 맞는 Path가 만들어집니다.

`name`은 마지막 파일명 전체, `stem`은 마지막 확장자를 뺀 이름, `suffix`는 마지막 확장자입니다. `archive.tar.gz`의 stem은 `archive.tar`, suffix는 `.gz`이고, `suffixes`는 `['.tar', '.gz']`입니다. 확장자는 관례일 뿐 파일 내용이나 안전성을 보장하지 않습니다.

`mkdir(exist_ok=True)`는 폴더가 이미 있어도 오류를 내지 않습니다. `write_text(..., encoding='utf-8')`와 `read_text`는 텍스트 인코딩을 명시합니다. 바이너리 이미지나 압축 파일은 `read_bytes`·`write_bytes` 또는 바이너리 모드를 사용해야 합니다.

[따라하기]
아래 내용을 path_demo.py로 저장하세요.

```python
from pathlib import Path

def safe_child(base, name):
    candidate = (base / name).resolve()
    if candidate.parent != base:
        raise ValueError("direct child path only")
    return candidate

base = Path("path_lab").resolve()
base.mkdir(exist_ok=True)
note = safe_child(base, "notes.txt")
note.write_text("첫 파일\n", encoding="utf-8")

for path in [note, Path("archive.tar.gz"), Path(".env")]:
    print(
        f"{path.name}: stem={path.stem!r}, "
        f"suffix={path.suffix!r}, suffixes={path.suffixes}"
    )

print("relative:", note.relative_to(base))
print("content:", note.read_text(encoding="utf-8").strip())
```

Windows PowerShell에서는 `py path_demo.py`, macOS·Linux에서는 `python3 path_demo.py`를 실행합니다. 예상 결과는 같습니다.

```text
notes.txt: stem='notes', suffix='.txt', suffixes=['.txt']
archive.tar.gz: stem='archive.tar', suffix='.gz', suffixes=['.tar', '.gz']
.env: stem='.env', suffix='', suffixes=[]
relative: notes.txt
content: 첫 파일
```

현재 폴더에 `path_lab/notes.txt`가 생깁니다.

[흔한 실수]
실행 파일이 있는 폴더와 현재 작업 폴더를 같다고 가정하지 마세요. 상대 경로는 보통 현재 작업 폴더 기준입니다. 문자열에서 Windows 역슬래시는 이스케이프 문자로 해석될 수 있으므로 Path를 사용하세요.

[보안 주의]
사용자 입력을 그대로 `base / name`에 붙이면 `../`를 이용해 허용 폴더 밖을 가리키는 경로 순회가 생길 수 있습니다. 업로드는 확장자만 신뢰하지 말고 크기와 실제 형식을 검사하며 서버가 새 이름을 생성하세요. 비밀키나 환경 파일을 공개 폴더에 저장하지 않습니다.

[직접 해볼 과제]
1. notes.txt를 diary.md로 바꾸고 출력되는 stem과 suffix를 기록하세요.
2. `reports` 하위 폴더를 허용하도록 검증 규칙을 설계하되 base 밖은 거부하세요.
3. `Path.cwd()`와 `Path(__file__).resolve().parent`를 출력해 차이를 비교하세요.

[확인문제]
1. 상대 경로는 무엇을 기준으로 해석되나요?
2. archive.tar.gz의 suffix와 suffixes는 각각 무엇인가요?
3. 업로드 파일의 안전성을 확장자만으로 판단하면 안 되는 이유는 무엇인가요?

[다음 학습]
CORE-006에서는 환경변수와 설정 파일을 다루며 경로와 비밀값을 코드에서 분리합니다.

[공식 참고 자료]
Python pathlib: https://docs.python.org/3/library/pathlib.html
Python 파일 읽기·쓰기: https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
Python os.path: https://docs.python.org/3/library/os.path.html
POSIX 경로 정의: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
1,241
어제
5,103
최대
16,772
전체
772,295
Copyright © 소유하신 도메인. All rights reserved.