본문 바로가기

Language/Python

[Python] 드라이브의 경로 가져오기


[그림. 1] Drives



기존에 작성했던 루트에서 작성하면 문제될 것이 없었는데, 함수화 시켜버리면 ValueError 를 뿜어내서 다시 정리를 해본다.



로컬 드라이브 또는 이동식 저장장치 중, 인식되어 있는 녀석들의 드라이브 명을 알아내는 소스를 검색하다가

알게 된 것...


이거 땜에 무슨 HID Device를 쪼물딱 거릴 때 쓰는 패키지도 깔고 그랬지만 그냥 이게 젤 편한 것 같다.


그러나... 멀티리더기를 처리할 수 없는 장벽을 만나서 아직은 더 검색해야 한다. ㅠㅠ


멀티 리더기는 usb가 안 꼽혀 있어도 드라이브가 활성화 되어 있기에 그걸 건드리면 윈도우가 애러를 내뱉는다.


usb가 꼽혔는지 안 꼽혔는지 확실히 체크하려면 드라이브에 접근하는 어떠한 함수라도 써야 하는데, 그 짓을 했다가


애러가 터지는 것...


일반 USB 드라이브는 장치를 연결할 때에 디바이스가 활성화 되는 반면 멀티리더기는 그냥 계속 활성화 상태라서


좀 짜증이 난다.



밑의 코드가 바로 함수화를 안 하면 잘 되는데, 함수화 시키면 애러를 뿜었던 코드이다.


# -*- coding: utf-8 -*-

import win32api
import win32file
import os

#
# cut-and-pasted from MSDN
#
DRIVE_TYPES = """
0 Unknown
1 No Root Directory
2 Removable Disk
3 Local Disk
4 Network Drive
5 Compact Disc
6 RAM Disk
"""
drive_types = dict((int (i), j) for (i, j) in (l.split ("\t") for l in DRIVE_TYPES.splitlines () if l))

drives = (drive for drive in win32api.GetLogicalDriveStrings ().split ("\000") if drive)
# for drive in drives:
# type = drive_types[win32file.GetDriveType (drive)]
# if type == 'Removable Disk':
# print drive

drive_list = []

for drive in drives:
type = drive_types[win32file.GetDriveType (drive)]
if type == 'Removable Disk':
try:
drive_list.append(type)
except WindowsError, e:
pass


이 것을 함수(메소드)로 사용해도 애러가 나지 않도록 검색하고 알아내서 정리한 코드는 이것이다.

그리고 코드 자체를 다 뜯어 고치니깐 위에 언급했떤 멀티리더기의 빈 드라이브가 인식된 상태에서도 에러가 나지 않는다. ㅋ


def get_drive(self):
"""DRIVE_TYPES
0 Unknown // win32file.DRIVE_UNKNOWN
1 No Root Directory // win32file.DRIVE_NO_ROOT_DIR
2 Removable Disk // win32file.DRIVE_REMOVABLE
3 Local Disk // win32file.DRIVE_FIXED
4 Network Drive // win32file.DRIVE_REMOTE
5 Compact Disc // win32file.DRIVE_CDROM
6 RAM Disk // win32file.DRIVE_RAMDISK
"""
drive = GetLogicalDriveStrings()
drive = drive.split('\000')[:-1]
drive_list = []
rdrive = []

for drv in drive:
if win32file.GetDriveType(drv) == win32file.DRIVE_REMOVABLE:
drive_list.append(drv)
for drv in drive_list:
try:
if os.path.getsize(drv) >= 0:
rdrive.append(drv)
except OSError:
pass
return rdrive


os.path.getsize() 메소드를 쓰는 이유는 멀티리더기의 빈 드라이브를 걸러내기 위함이다.


빈 드라이브를 검색 시 익셉션이 발생하기 때문에 except로 pass를 시켜 재껴버린다.

(분명 첫 번째 코드에서는 except pass를 해도 에러가 터졌는데 코드를 싹 다 바꾸니 잘 된다. -_-)


결국 win32api와 win32file 패키지를 이용하는 것이고 드라이브의 속성(이름)에 따라서 내가 원하는 속성을 갖는 드라이브를 가져다가 쓰면 되겠다.


주석 처리 해놓은 부분은 드라이브 타입에 따른 번호와 뜻을 열거한 거고, 각 번호 별로 win32file에 정의된 맴버와 어떻게 매칭되는지를 보여주는 것이다.


로지컬 드라이브 스트링을 모두 긁어온 뒤에 각 드라이브 별로 로컬인지, 이동식 디스크 인지, 시디롬인지를 for if 문을 통해 걸러내주면 되는 것이다.


두 번째 코드에서는 DRIVE_REMOVABLE, 즉 이동식 디스크만을 리스트로 따로 묶어주고 있는 것이다.