파일 IO와 폴더 생성, 허가권 등 여러 내용을 공부했다.

사용한 모듈은 os, sys, pickle, shutil이다.


============================== Python ==============================

# 파일 이름의 위치로 접근

f = open('test.txt', 'w', encoding='UTF-8-sig')

f.write('abc')

print('첫번째 현재 위치 반환: ', f.tell())

f = open('test.txt', 'r', encoding='UTF-8-sig')

f.seek(0)

print('첫번째 현재 위치 반환: ', f.tell())

print('한 문자 읽기: ', f.read(1))

print('두번재 현재 위치 반환: ', f.tell())

'''

'결과'

첫번째 현재 위치 반환:  0

한 문자 읽기:  a

두번재 현재 위치 반환:  4


'해석'

encoding='UTF-8-sig'를 잘 생각해야지 이해를 할 수 있다.

맨처음 seek(0)을 통해 포인터를 제일 앞으로 가져가고 그다음 맨처음 나오는 문자가

3번에 위치함을 알 수 있다. 이는 UTF-8-sig로 인코딩을 하면 앞에 FE BB BF 중 하나가

나타나게 되는데 이것 때문에 커서의 위치가 3번부터 문자를 읽을 수 있는 것이다.

예시로 seek(1) 혹은 seek(2)를 테스트해보면 

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 0: invalid start byte

위와 같은 오류가 발생하게 된다.


ref.

Documentation 3.6 Python

https://docs.python.org/3/library/codecs.html

wystan's tales / UTF-8 인코딩에서의 BOM 문제

http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem

'''


# 파일 입출력 모듈 사용

import sys

f=open('test.txt', 'w', encoding='UTF-8-sig')

sys.stdout=f

print('표준 출력으로 입력')  # 이 부분이 test.txt에 저장된다. test.txt를 열어보면 '표준 출력으로 입력'이 있다.

f.close()


# pickle

import pickle

a = {'홍길동':4358382, '전우치':9465215}

b = ['string', 1234, 0.2345]

c=(a,b)

f=open('test.txt','wb')  # wb는 write binary로 직렬화한다는 뜻이다.

pickle.dump(c,f)  # c를 f에 넣는다는 뜻

f.close( )


import pickle

f=open('test.txt','rb')

x,y=pickle.load(f)  # load를 통해 직렬화된 데이터를 가져와서 각각 x, y에 할당한다.

print(x)  # 결과는 {'홍길동': 4358382, '전우치': 9465215}.

print(y)  # 결과는 ['string', 1234, 0.2345].


import pickle

a = [1,2,3]

print(pickle.dumps(a))

print(pickle.loads(pickle.dumps(a)))

'''

'결과'

b'\x80\x03]q\x00(K\x01K\x02K\x03e.'   <- 직렬화 된 형태

[1, 2, 3]     <- 역직렬화를 통해 알 수 있는 형태로 변환

'''


##### 파일의 관리

### 파일의 목록

#파일 전체 내용 확인: os 모듈의 listdir 메서드로 디렉토리에 존재하는 전체 내용을 리스트로 반환한다.

import os

print(os.getcwd())

print(os.listdir())

'''

'결과'

D:\PyCharmData

['.idea', '20180509.py', '20180510.py', '20180514.py', '20180515.py', 

    '20180516.py', '20180517.py', '20180518.py', '20180521.py', '20180523.py', 

    '20180528.py', '20180529.py', '20180530.py', 'ss.py', 'test.py', 'test.txt', 

    'venv']

'''


# 현재 디렉토리 파일 내용 확인: os 모듈의 listdir 메서드의 인자값에 ./와 .을 지정하여

#                                  현재 디렉토리에 있는 파일 목록을 리스트로 반환한다.

import os

print(os.listdir('./'))

print(os.listdir('.'))

'''

'결과'

['.idea', '20180509.py', '20180510.py', '20180514.py', '20180515.py', 

    '20180516.py', '20180517.py', '20180518.py', '20180521.py', '20180523.py', 

    '20180528.py', '20180529.py', '20180530.py', 'ss.py', 'test.py', 'test.txt', 

    'venv']

['.idea', '20180509.py', '20180510.py', '20180514.py', '20180515.py', 

    '20180516.py', '20180517.py', '20180518.py', '20180521.py', '20180523.py', 

    '20180528.py', '20180529.py', '20180530.py', 'ss.py', 'test.py', 'test.txt', 

    'venv']

'''


# 부모 디렉토리 파일 내용 확인: os 모듈의 listdir 메서드의 인자값에 ‥/을 지정하여

#                               현재 디렉토리의 부모 디렉토리에 있는 파일 목록을 리스트로 반환한다.

import os

print(os.listdir('../'))

'''

'결과'

['!$axVKj', '$RECYCLE.BIN', 'a', 'DB', 'Downloads', 'mongodb', 'mongojava', 

    'myLibraries', 'PyCharmData', 'Python', 'R', 'repository', 'Rstart.7z', 

    'Rtest', 'System Volume Information', 'upload', 'workspace', '딥러닝자료', 

    '화면캡쳐']


'''




### 파일의 종류

# is~ 메서드

import os

def filetype(fpath):

    print(fpath, end=' : ')  # 파일이름 : ~   형태로 나온다.

    if os.path.isfile(fpath):  # 파일인지 확인

        print('파일')

    if os.path.isdir(fpath):  # 디렉토리인지 확인

        print('디렉토리')

    if os.path.islink(fpath):  # 심볼릭 파일인지 확인

        print('심볼릭 파일')

filelist=os.listdir( )

for i in filelist: filetype(i)

'''

'결과'

.idea : 디렉토리

20180509.py : 파일

20180510.py : 파일

20180514.py : 파일

20180515.py : 파일

20180516.py : 파일

20180517.py : 파일

20180518.py : 파일

20180521.py : 파일

20180523.py : 파일

20180528.py : 파일

20180529.py : 파일

20180530.py : 파일

ss.py : 파일

test.py : 파일

test.txt : 파일

venv : 디렉토리

'''


### 파일의 허가권

# 허가권과 존재 확인

'''

access(경로, 모드) 메서드의 모드로 파일이나 디렉토리의 허가권과 존재를 확인하며 

일반적으로 소유자가 가지고 있는 권한을 테스트한다. 


① os.F_OK : 파일 자체가 존재하는지를 확인한다. 

② os.R_OK : 읽기 권한이 있는지를 확인한다. 

③ os.W_OK : 쓰기 권한이 있는지를 확인한다. 

④ os.X_OK : 실행 권한이 있는지를 확인한다. 

'''


import os

def filetype(fpath):

    print(fpath, end=' : ')

    if os.access(fpath, os.F_OK):

        print(end='파일(디렉토리) 확인 후 권한 확인: ')

    if os.access(fpath, os.R_OK):

        print(end='r')

    if os.access(fpath, os.W_OK):

        print(end='w')

    if os.access(fpath, os.X_OK):

        print('x')

filelist=os.listdir( )

for i in filelist: filetype(i)

'''

'결과'

.idea : 파일(디렉토리) 확인 후 권한 확인: rwx

20180509.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180510.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180514.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180515.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180516.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180517.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180518.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180521.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180523.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180528.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180529.py : 파일(디렉토리) 확인 후 권한 확인: rwx

20180530.py : 파일(디렉토리) 확인 후 권한 확인: rwx

ss.py : 파일(디렉토리) 확인 후 권한 확인: rwx

test.py : 파일(디렉토리) 확인 후 권한 확인: rwx

test.txt : 파일(디렉토리) 확인 후 권한 확인: rwx

venv : 파일(디렉토리) 확인 후 권한 확인: rwx

'''


# 허가권의 변경

'''

⎼chmod 메서드의 모드로 파일이나 디렉토리의 허가권을 변경한다. 

⎼유닉스의 경우에는 읽기(r) 권한의 숫자 모드는 4이며 쓰기(w) 권한의 숫자 모드는 2이고 

    실행(x) 권한의 숫자 모드는 1을 가지므로 만약에 모든 권한을 주려면 4+2+1=7로 7의 값을 지정하면 된다. 

⎼유닉스의 기본 권한은 0777이 되는데 첫 번째 7은 소유자 권한이고 두 번째 7은 

    소유자가 속한 그룹 권한이고 마지막 7은 모든 사용자 권한이다. 

⎼0755는 소유자는 모든 권한을 가지고 소유자가 속한 그룹과 모든 사용자는 4+1=5이므로 

    쓰기 권한을 부여되지 않는다. 

⎼윈도우는 기본적으로 숫자 모드로 권한을 설정해도 권한이 바뀌지 않으므로 

    파이썬에서 chmod 메서드로 숫자 모드로 권한을 변경하면은 불규칙적으로 변경이 되지만 

    실제로 변경되는 것이 아니다. 

'''

import os

def filetype(fpath):

    print(fpath, end=' : ')

    if os.access(fpath, os.F_OK):

        print(end='파일(디렉토리) 확인 후 권한 확인: ')

    if os.access(fpath, os.R_OK):

        print(end='r')

    if os.access(fpath, os.W_OK):

        print(end='w')

    if os.access(fpath, os.X_OK):

        print('x')

os.chmod('test.txt', 555)

filetype('test.txt')  # 결과는 test.txt : 파일(디렉토리) 확인 후 권한 확인: rx.


### 파일의 조작

# 파일의 이름 변경

import os

os.rename('retest.txt','newtest.txt')  # retest.txt -> newtest.txt 로 바꾼다.


# 파일의 이동

import os

os.rename('newtest.txt','test/newtest.txt')  # newtest.txt -> test/newtest.txt 경로를 바꾸면서 이름도 바꿀 수 있다.

                                                  # 원래 있던 파일은 없어지고 새로운 경로에 파일이 생긴다.


### 파일의 조정

# 상대경로를 절대 경로로 변환

import os

print(os.path.abspath('mintest.txt'))  # 결과는 D:\PyCharmData\mintest.txt.


# 주어진 경로의 파일 확인

import os

a='test.txt'

b='\\pycharmData\\temp\\min.txt'

print('상대경로에서 확인: ',os.path.exists(a))  # 결과는    상대경로에서 확인:  True

print('절대경로에서 확인: ',os.path.exists(b))  # 결과는    절대경로에서 확인:  False


# 경로의 표시 및 구분자

import os

print('현재 디렉토리 표시: ',os.curdir)  # 결과는    현재 디렉토리 표시:  .

print('부모 디렉토리 표시: ',os.pardir)  # 결과는    부모 디렉토리 표시:  ..

print('디렉토리 분리 구분자: ',os.sep)   # 결과는    디렉토리 분리 구분자:  \


# 경로와 파일명으로 분리

import os

a='/pycharmData/temp/min.txt'

print('절대경로에서 파일명 추출:',os.path.basename(a))  # 결과는 절대경로에서 파일명 추출: min.txt

print('절대경로에서 디렉토리 경로 추출:',os.path.dirname(a))  # 결과는 절대경로에서 디렉토리 경로 추출: /pycharmData/temp


# 경로와 파일명을 한 번에 분리

import os

a='/pycharmData/temp/min.txt'

print('절대경로에서 파일명과 디렉토리 경로 추출:',os.path.split(a))

'''

'결과'

절대경로에서 파일명과 디렉토리 경로 추출: ('/pycharmData/temp', 'min.txt')

'''


# Ms 윈도우즈에서 드라이브명과 파일 경로명을 분리

import os

a='/pycharmData/temp/min.txt'

print('절대경로에서 드라이브명과 디렉토리 경로 추출:',os.path.splitdrive(a))

'''

'결과'

절대경로에서 드라이브명과 디렉토리 경로 추출: ('', '/pycharmData/temp/min.txt')

'''


# 확장자 분리

import os

a='/pycharmData/temp/min.html'

print('절대경로에서 확장자 분리:',os.path.splitext(a))  # 절대경로에서 확장자 분리: ('/pycharmData/temp/min', '.html')






### shutil 모듈을 활용한 파일의 작업

# 파일 복사

import shutil

shutil.copy('min.txt','so1')

shutil.copyfile('min.txt','so2')

shutil.copy('min.txt','so3.txt')

shutil.copyfile('min.txt','so4.txt')

shutil.copy('min.txt','so5.html')

shutil.copyfile('min.txt','so6.html')

'''

'결과'

파일이 복사되어 각각 so1, so2, so3.txt, so4.txt, so5.html, so6.html이 생성되었다.

'''


# 파일의 이동

import shutil

shutil.move('min.txt','temp')

shutil.move('sample.txt','newsample.txt')

'''

'결과'

os.rename과 같은 결과를 얻었다.

'''




### 디렉토리의 관리

# 디렉토리 생성

import os

print('디렉토리 생성:', os.mkdir('one'))

print('디렉토리 생성 및 권한:', os.mkdir('auth',755))

'''

'결과'

디렉토리 생성: None

디렉토리 생성 및 권한: None

'''


import os

print('하위 디렉토리 생성:', os.makedirs('temp/two/three'))

'''

'결과'

하위 디렉토리 생성: None

'''


# 디렉토리의 삭제

import os

print('디렉토리 삭제:', os.rmdir('one'))

print('하위 디렉토리 삭제:', os.rmdir('temp/two/three'))

'''

'결과'

디렉토리 삭제: None

하위 디렉토리 삭제: None

'''


import os

print('모든 디렉토리 삭제:',os.removedirs('temp/two/three'))

'''

'결과'

모든 디렉토리 삭제: None

'''




### 디렉토리의 탐색

# 현재 디렉토리의 탐색

import os

for dirpath, dirname, filename in os.walk(os.getcwd( )):

    print('탐색하고 있는 디렉토리 경로',dirpath)

    print('하위 디렉토리',dirname)

    print('파일 리스트',filename)

'''

'결과'

탐색하고 있는 디렉토리 경로 D:\PyCharmData

하위 디렉토리 ['.idea', 'auth', 'test', 'venv']

파일 리스트 ['20180509.py', '20180510.py', '20180514.py', '20180515.py', 

    '20180516.py', '20180517.py', '20180518.py', '20180521.py', 

    '20180523.py', '20180528.py', '20180529.py', '20180530.py', 

    'newsample.txt', 'so1', 'so2', 'so3.txt', 'so4.txt', 'so5.html', 

    'so6.html', 'ss.py', 'test.py']

탐색하고 있는 디렉토리 경로 D:\PyCharmData\.idea

하위 디렉토리 []

파일 리스트 ['encodings.xml', 'misc.xml', 'modules.xml', 'PyCharmData.iml', 'workspace.xml']

탐색하고 있는 디렉토리 경로 D:\PyCharmData\auth

하위 디렉토리 []

파일 리스트 []

탐색하고 있는 디렉토리 경로 D:\PyCharmData\test

하위 디렉토리 []

파일 리스트 []

탐색하고 있는 디렉토리 경로 D:\PyCharmData\venv

하위 디렉토리 ['Include', 'Lib', 'Scripts']

파일 리스트 ['pyvenv.cfg']

.

.

.

(중략)

.

.

.

탐색하고 있는 디렉토리 경로 D:\PyCharmData\venv\Lib\tcl8.6

하위 디렉토리 []

파일 리스트 ['init.tcl']

탐색하고 있는 디렉토리 경로 D:\PyCharmData\venv\Scripts

하위 디렉토리 []

파일 리스트 ['activate', 'activate.bat', 'Activate.ps1', 

    'deactivate.bat', 'easy_install-3.5-script.py', 

    'easy_install-3.5.exe', 'easy_install-script.py', 

    'easy_install.exe', 'pip-script.py', 'pip.exe', 'pip3-script.py', 

    'pip3.5-script.py', 'pip3.5.exe', 'pip3.exe', 'pyexpat.pyd', 

    'pyexpat_d.pyd', 'python.exe', 'python3.dll', 'python35.dll', 

    'python35_d.dll', 'python3_d.dll', 'pythonw.exe', 'pythonw_d.exe', 

    'python_d.exe', 'select.pyd', 'select_d.pyd', 'sqlite3.dll', 

    'sqlite3_d.dll', 'tcl86t.dll', 'tcl86tg.dll', 'tk86t.dll', 

    'tk86tg.dll', 'unicodedata.pyd', 'unicodedata_d.pyd', 

    'vcruntime140.dll', 'winsound.pyd', 'winsound_d.pyd', '_bz2.pyd', 

    '_bz2_d.pyd', '_ctypes.pyd', '_ctypes_d.pyd', '_ctypes_test.pyd', 

    '_ctypes_test_d.pyd', '_decimal.pyd', '_decimal_d.pyd', 

    '_elementtree.pyd', '_elementtree_d.pyd', '_hashlib.pyd', 

    '_hashlib_d.pyd', '_lzma.pyd', '_lzma_d.pyd', '_msi.pyd', 

    '_msi_d.pyd', '_multiprocessing.pyd', '_multiprocessing_d.pyd', 

    '_overlapped.pyd', '_overlapped_d.pyd', '_socket.pyd', 

    '_socket_d.pyd', '_sqlite3.pyd', '_sqlite3_d.pyd', '_ssl.pyd', 

    '_ssl_d.pyd', '_testbuffer.pyd', '_testbuffer_d.pyd', 

    '_testcapi.pyd', '_testcapi_d.pyd', '_testimportmultiple.pyd', 

    '_testimportmultiple_d.pyd', '_testmultiphase.pyd', 

    '_testmultiphase_d.pyd', '_tkinter.pyd', '_tkinter_d.pyd']

'''


# 모든 파일 txt 파일의 삭제

import os

for path, subdirs, files in os.walk('temp'):

    for filename in files:

        if filename.endswith('.txt'):

            fullpath = os.path.join(path,filename)

            print('삭제한 파일:', fullpath)

            os.remove(fullpath)

'''

'결과'

삭제한 파일: temp\min1.txt

삭제한 파일: temp\min2.txt

삭제한 파일: temp\min3.txt

'''




### shutil 모듈을 활용한 디렉토리의 작접

# 디렉토리의 복사

import shutil

shutil.copytree('temp','newtemp')

shutil.copytree('onedir','newonedir')


# 디렉토리의 삭제

import shutil

shutil.rmtree('del')


============================== Python ==============================

+ Recent posts