반응형

본 프로그램은 python 2.7.13에서 제작되었습니다. 


파이썬에서도 C와 마찬가지로 파일 입출력이 가능한 명령어들이 존재한다.


이번 게시물에서는 파이썬에서의 파일 입출력 방식을 알아보고자 한다.


우선 파일을 .txt로 제한하고 내용을 기술하고자 한다.


파일을 다루기 위해서는 우선 파일을 열어야 한다.




1. 파일 열기


파일객체 = open(파일명, 모드) 로 구성된다

ex) fhandle = open('test.txt', 'r')


모드 종류는 다음과 같고, 복합적으로 사용이 가능하다. ex) 'wb' :: 바이너리 쓰기 모드


바로 예제를 통해 확인해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fhandle = open('site.txt''r'# 모드가 없는 경우 default는 'r'이다.
 
print 'type :', type(fhandle)
print 'fhandle :', fhandle
 
line = 0
for i in fhandle:
    line += 1
    
    # txt파일의 줄바꿈을 없애준다.
    # 왜냐면 print자체에도 줄바꿈이 있기에
    # 엔터가 두번 쳐지는 출력화면이 나오기 때문이다.
    # rstrip() 또는 print i, end=''를 해주면 된다.(python 3)
    print i.rstrip()
 
# fhandle를 for문을 통해 돌리면 행 단위로 글을 읽어내기에
# line 수가 총 5임을 알 수 있다.
print line    
    
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


site.txt


위의 site.txt를 이용하여 open을 시도하고 있다.

(참고로 파이썬 코드가 위치한곳과 열고자 하는 파일의 위치가 같은곳에 있어야 한다.(경로를 지정해주지 않는 이상))



타입은 file라고 나오고 있고, fhandle을 print하니 파일 핸들 정보가 나온다.



** 핸들이 뭐에요??


핸들이란, 현재 우리가 쓰는 프로그램(파이썬)과 파일을 이어주는 파이프, 연결통로 같은 역할을 해준다.


이 파이프가 있어야 파일과 프로그램사이 정보가 교환이 된다.




그리고 for문을 통해 fhandle을 돌려보면 알 수 있는 내용은


i는 각 행의 내용을 가지고 있게 되고, 파일이 가지고 있는 라인 수(행의 수) 만큼 돌게된다.


따라서 line은 5가 출력이 된다.




또 다른 예제를 만들어보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fhandle = open('site.txt''r'# 모드가 없는 경우 default는 'r'이다.
 
blog = []
 
for i in fhandle:
    if 'www' in i:
        print i.rstrip()
    else:
        blog.append(i.rstrip())
 
print blog
 
# list의 index를 split하여 또 리스트로 만든 뒤, bloglist로 넣는다.
bloglist = blog[0].split('.')
 
# bloglist또한 현재 list이다.
print bloglist
for i in bloglist:
    print i
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


for문에서 현재 행에 www라는 값이 존재한다면 i를 출력하고, 그게 아니라면 blog 리스트에 push해주는 과정이다.


결국 programbasic.tistory.com이 blog 리스트에 들어가게 되고,


bloglist에는 blog의 첫번째 인덱스에있는 programbasic.tistory.com을 '.'을 구분자로하여 split하여 넣어준다.


split의 리턴값은 리스트이므로 결국 bloglist 또한 list가 된다.






이번에는 for문을 이용하지 않고 바로 read 하는 과정을 보고자 한다.


1
2
3
4
5
6
7
8
9
fhandle = open('site.txt''r'# 모드가 없는 경우 default는 'r'이다.
 
readAll = fhandle.read()
 
print readAll
 
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus



우선 핸들을 받아두고 readAll 이라는 변수에 fhandle.read()를 해주면 


readAll은 str형으로 변환되고, fhandle이 가지고 있던 파일의 정보를 모두 readAll에 옮겨주게 된다.




위의 모든 코드에서 잘못된 점은 무엇일까??


실행이 되는데 뭐가 잘못됐냐니 질문 자체가 이상할 수 있다.


하지만 조금 더 섬세한 코더가 되기 위해서는 fhandle.close() 를 꼭 써주자!!!


파일을 열었으면 닫아야 하는법.














2. 파일 쓰기


파일 쓰기는 읽기보다는 쉽다.


하지만 텍스트 파일에 한해서 쉬운 내용이니, 다른 여러 파일에 대해 이해가 필요한 것은 더 많은 검색을 통해 알아가길 바란다.


군더더기 없이 간단하게 output.txt를 만드는 과정만 설명하고 파일 쓰기를 마치고자 한다.


1
2
3
4
5
6
7
8
9
10
fhandle = open('output.txt''w')
 
string = 'hello world !! today is 2017-07-04'
 
fhandle.write(string)
 
fhandle.close()
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus



fhandle을 통해 output.txt를 쓰기 전용으로 열어준다.


그리고 원하는 string 혹은 원하는 내용을 기입한다.


마지막으로 핸들을 이용하여 쓰고자하는 것을 보내준다.


쓰기에서는 더더욱 중요해지는 fhandle.close()를 통해 닫아준다.


파일을 닫지 않으면 결국 파일이 써지지 않는다.(영원히 열린 채 저장이 되지 않는다.)





3. 응용



파일이 존재하지는지 try, except를 통해 확인해보는 프로그램


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#-*- coding: utf-8 -*-
 
while True:
    try:
        file_name = raw_input('Enter file name: ')
        file_handle = open(file_name, 'r')
        print 'File is opened sucessfully: ', file_name
        break
    except:
        print 'File cannot be opened: ', file_name
 
print 'done'
file_handle.close()
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus



파일을 열때 try, except를 통해 파일이 존재하면 열고, 그렇지 않다면 except 구문으로 넘겨준다.






파일을 복사하는 프로그램(4가지 방식)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#-*- coding: utf-8 -*-
 
def filecopy(fhandle,chandle):
 
    try:
    # method 1 use fhandle -> return str (line by line)
 
        for i in fhandle:
            chandle.write(i)
            
    # method 2 read() -> return str
 
    #    get = fhandle.read()
    #    chandle.write(get)
 
    # method 3 readline() -> return str (if done, return '')
 
    #    while True:
    #        get = fhandle.readline()
 
    #        if get == '':
    #            break
 
    #        chandle.write(get)
 
    # method 4 readlines() -> return list       
 
    #    get = fhandle.readlines()
    #    for i in get:
    #        chandle.write(i)
 
        return True
 
    except:
        return False
 
while True:
    try:
        rname = raw_input('read file name :: ')
        rhandle = open(rname,'r')
 
        while True:
            try:
                wname = raw_input('copy file name :: ')
 
                whandle = open(wname, 'w')
 
                if filecopy(rhandle, whandle):
                    break
                else:
                    print 'can not finish. please retry'
                    continue
                
            except:
                print 'please retry valid copy file name'
 
        break
 
    except:
        print 'please retry valid read file name'
 
rhandle.close()
whandle.close()
 
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


1. handle을 통해 파일 복사

handle을 가지고 for i in rhandle을 이용하여 whandle.write(i)를 해준다면 한라인씩 복사가 된다.


2. read() 메소드를 통한 복사

string = rhandle.read()를 통해 rhandle이 가지고 있는 모든 파일 내용을 string에 넣어주고 바로 whandle.write(string)을 해주면 된다.


3. readline() 메소드를 통한 복사

readline() 메소드를 이용하면 한줄씩 읽어 나가게 되고 결국 while문 내에서 return값이 ''가 되기 전까지 복사를 해주면 된다.
(readline() 메소드의 리턴값은 각 행에 내용이 존재하면 내용을 리턴, 없으면 ''를 리턴한다.)


4. readlines() 메소드를 통한 복사

readlines() 메소드를 이용하면 '\n'를 기준으로 list 형태로 리턴해준다. 따라서 그 리스트를 복사할 수 있게 된다.






파일에서 원하는 내용만 복사

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#-*- coding: utf-8 -*-
 
def filecopy(rhandle, whandle):
    try:
        # method 1 use handle -> return str(line by line)
 
        for i in rhandle:
             if 'am' in i:
                whandle.write(i)
 
        # method 2 use read() -> return str
 
        #get = rhandle.read()
        #rlist =  get.splitlines()
 
        #for i in rlist:
        #    if 'am' in i:
        #        whandle.write(i+'\n')
 
        # method 3 use readline() -> return str(if done, return '')
 
        #while True:
        #   get = rhandle.readline()
        #   if get == '':
        #       break
 
        #   if 'am' in get:
        #       whandle.write(get)
 
        # method 4 use readlines() -> return list
 
        #rlist = rhandle.readlines()
 
        #for i in rlist:
        #   if 'am' in i:
        #       whandle.write(i)
 
        return True
    
    except:
        return False
    
while True:
    try:
        rname = raw_input('read file name :: ')
        rhandle = open(rname, 'r')
 
        while True:
            try:
                wname = raw_input('write file name :: ')
                whandle = open(wname, 'w')
                
                if filecopy(rhandle, whandle):
                    break
                else:
                    print 'can not finish, please retry'
                    continue
 
            except:
                print 'please retry valid write file name.'
 
        break
    
    except:
        print 'please retry valid read file name.'
 
rhandle.close()
whandle.close()
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


위의 파일 복사 방식과 동일하고 if '원하는 내용' in 현재 읽어지는 구간: 을 통해 원하는 내용만 복사가 가능해진다.




자신이 입력한 내용을 파일에 저장하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#-*- coding: utf-8 -*-
 
def myWrite(whandle):
 
    wlist = []    
    while True:
        get = raw_input('input :: ')
 
        if get == 'done':
            break
 
        wlist.append(get+'\n')
 
    return wlist
 
wname = raw_input('write file name :: ')
 
whandle = open(wname, 'w')
 
wlist = myWrite(whandle)
 
for i in wlist:
    whandle.write(i)
    
whandle.close()
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus



특정 문자를 받기 전까지 계속해서 list에 담아둔 후, 그 값을 write하면 된다.(리스트에 담지 않고 바로 write를 해도 된다.)


반응형