Media Log

1. 파일 입출력(File Input/Output)

 

오늘은 파일 입출력에 대해서 알아보도록 하겠습니다. 전 강좌에서는 화면에서 출력하고 입력하는 방법을 알아봤다면, 이번에는 파일에 출력하고 입력하는 것을 알아보도록 하겠습니다. 파일을 읽고, 쓰고, 덧붙이는 등 세밀하게 작업을 위해 파이썬에서는 open이란 함수를 지원하는데 이 함수의 기본형은 아래와 같습니다.

파일객체 = open(file, mode)

기본적으로 들어가는 두 인자 중 file이란 인자에는 파일 이름이 이곳에 들어가고, mode에는 파일을 열 때 사용하는 모드를 말합니다. 여기서 파일을 열 때 사용하는 모드란 쓰기 모드, 읽기 모드 등과 같이 파일에 무언가를 쓸때는 쓰기 모드, 무언가를 읽어들일 때는 읽기 모드를 사용합니다. 아래에 mode에 들어갈 수 있는 것을 표로 정리해 두었습니다.

 

모드

설명

r

읽기 모드 (디폴트)

r+

읽기 + 쓰기 모드

w

쓰기 모드

a

쓰기 + 이어쓰기 모드

t

텍스트 모드 (디폴트)

b

바이너리 모드

 

위에 있는 모드들은 독립적으로 사용되는게 아니라, 서로 모드를 조합해서 사용이 가능합니다. 예를 들면, 'wb'는 바이너리 쓰기 모드가 되며 'rb'는 바이너리 쓰기 모드가 되는 것입니다. 파일을 쓰기 모드로 개방하여 임의의 문자열을 작성해보도록 할까요? 아래 예제를 보면서 open 함수를 통해 파일을 어떻게 만들고 쓰는지 알아보도록 합시다.

>>> f = open('t.txt', 'w')
>>> f.write('abcdefghijk')
11
>>> f.close()

위 예제의 1행을 보시면 't.txt란 파일을 쓰겠다'라는 의미가 됩니다. 이렇게 파일을 쓰기 모드로 열게 되면, 현재 디렉토리에 t.txt란 파일이 없다면 t.txt 파일을 새로 만들게 됩니다. 만약 이미 존재한다면 내용을 모두 지우고 새로 쓰게 되는 것입니다. 이어서 2행에서는 write란 함수를 통해서 파일에 임의의 문자열을 쓸 수 있는데, 이 write 함수는 말 그대로 파일에 문자열을 쓰고 싶을때 이용하는 함수입니다. 3행에서는 write 함수를 호출하여 몇 바이트나 썼는지 정수로 반환해준 값이 나온 것입니다. 마지막으로 4행에서는 파일의 사용이 모두 끝났으므로 파일 객체를 닫는 close 함수를 호출함으로써 마무리를 하게 됩니다. 이번에는 방금 쓴 파일을 읽어보도록 하겠습니다.

>>> f = open('t.txt', 'r')
>>> f.read()
'abcdefghijk'
>>> f.close()

위 예제의 1행에서는 't.txt란 파일을 읽겠다'라는 의미가 되며, 2행에서는 read란 함수로 파일을 모두 읽어들인 후, 읽은 데이터를 반환합니다. 3행에서는 close 함수로 파일을 닫습니다. 간단하죠? 이번에는 여러 줄을 파일에 써보도록 하겠습니다. 구구단 중 2단만 간단히 텍스트 파일에 작성해보도록 합시다.

>>> for i in range(1, 10):
	data = "2 * %d = %d\n" % (i, 2 * i)
	f.write(data)	
10
..
11
>>> f.close()

그리고 파일에 우리가 예상한 값이 쓰였는지 확인을 해보도록 합시다. 이번에는 read 함수가 아니라 readline이란 함수를 사용하여 파일을 읽어들여 보도록 하겠습니다. 아래를 한번 봅시다.

>>> f = open('gugudan.txt')
>>> line = f.readline()
>>> while line:
	print(line, end='')
	line = f.readline()
	
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
>>> f.close()

위 예제에서의 1행에서 mode가 비었는데, 읽기 모드가 기본값이므로 파일 이름만 명시해준 것입니다. 2행에서는 readline 함수를 사용하여 한번에 한줄씩 읽어들일 수 있습니다. 3행에서는 while문으로 반복을 하게 되는데, 이 때 line이 빈 문자열일 경우 즉, 더이상 읽어들인 문자열이 없을 경우에 반복문을 벗어나게 됩니다. 4행에서는 읽어들인 문자열에 이미 \n가 있기 때문에 끝문자(end)를 비워주는 것입니다. 5행에서는 현재 위치에서 다음 줄을 읽어들이기 위함이구요. 정상적으로 결과물이 출력됨을 확인한 후에, 파일 객체인 f를 닫습니다. 이 방법 말고도 또 파일을 읽어들이는 방법이 있는데, readline이 아니라 이번에는 readlines이란 함수를 이용하는 방법입니다. 한번 보시죠.

>>> f = open('gugudan.txt')
>>> lines = f.readlines()
>>> for line in lines:
	print(line, end='')
	
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
>>> f.close()

위 예제의 2행에서는 readlines 함수를 사용하여 파일의 내용 전체를 줄 단위로 잘라서 리스트에 저장하여, 저장한 리스트를 반환시켜서 lines에 넣습니다. 3~4행에서는 for문을 이용하여 리스트를 순차적으로 읽고 출력하는 것을 보실 수 있습니다. 역시 마지막은 close 함수를 통해 마무리를 짓습니다. 이번에는 파일 입출력에서 빠질 수 없는 tell과 seek 함수에 대해서 보도록 하겠습니다. tell 함수는 현재 파일의 위치를 반환하고, seek 함수는 현재 파일의 위치를 지정한 곳으로 이동시킵니다.

>>> f = open('hangul.txt', 'w')
>>> f.write('가나다\n라마바\n사아자\n차카타\n파하')
18
>>> f.close()

위의 파이썬 코드로 쓰여진 텍스트 파일을 한번 읽어보면서 seek와 tell 함수를 사용하여 보도록 하겠습니다.

>>> f = open('hangul.txt', 'r')
>>> f.tell()
0
>>> f.read()
'가나다\n라마바\n사아자\n차카타\n파하'
>>> f.tell()
36
>>> f.seek(0)
0
>>> f.tell()
0
>>> f.readline()
'가나다\n'
>>> f.tell()
8
>>> f.close()

위 예제의 2행에서는 tell 함수가 사용되었는데, tell 함수의 반환값이 0입니다. 이는 현재 파일의 위치가 0에 있음을 나타내며, 파일 위치는 현재 파일에서 어디까지 읽거나 썼는지를 나타내는 위치입니다. 4행에서 파일에 있는 내용을 모두 읽어들이고, 6행에서 tell 함수를 사용하여 위치를 확인해 보았더니 36이란 값이 나왔습니다. 그 후에 8행에서 seek 함수를 통해 파일 위치를 0으로 지정하고, 다시 tell 함수를 사용해 위치를 확인해 보았더니 0이란 값이 나왔습니다. 이어서 12행의 readline 함수를 사용한 뒤에, 14행에서 tell 함수를 사용해 보았더니 파일의 위치가 8임을 알 수 있었습니다. 이해 되시죠? 이쯤이면 파일을 읽거나 쓰는법, 그리고 파일 위치(파일 포인터)를 어느정도 응용하여 사용할 수도 있을 것입니다.

저작자 표시 비영리 변경 금지
신고
  1. ZiNee at 2013.12.23 18:27 신고 [edit/del]

    좋은 강좌 감사합니다. ^^*

    Reply
  2. 파이쑨 at 2014.01.03 19:14 신고 [edit/del]

    정말잘배우고 있습니다. ㄳ

    Reply
  3. 디렉토리 at 2014.01.08 12:53 신고 [edit/del]

    현재 디렉토리에서 파일을 연다고 했는데 c드라이브가 아닌 휴대용 장치(ex,핸드폰,mp3)에서의 파일은 열수가 없나요?없다면 열 수 있는 다른 방법이 없을 까요??

    Reply
  4. dimebagg at 2014.04.27 12:03 신고 [edit/del]

    안녕하세요 강좌 감사합니다 그런데 혹시 데이터 파싱 코드에서 한 폴더 안에 있는 많은 파일들을 반복적으로 열게 해주는 방법이 있나요?? 그러니까 만약 데이터 파일이 data-1, data-2, ... ,data-100까지 있을 때 저렇게 파일을 열어 원하는 데이터를 뽑고 다른 형식으로 저장하려고 하는데 이런 상황에서 반복문을 쓸 수 있나요??

    Reply
    • BlogIcon EXYNOA at 2014.04.28 19:23 신고 [edit/del]

      가능합니다. 반복문을 통해 특정한 형식을 띄는 여러개의 파일을 내장 함수 open를 통해 열고 작업할 수 있습니다.

    • dimebagg at 2014.04.28 20:46 신고 [edit/del]

      답변 감사합니다! 그럼 혹시 이런 방법으로 해도 될까요??
      for i in range(1,100)
      f = open('data-i', 'rb')
      ....
      여기서 open 함수 안의 파일명에 변수 i를 넣어서 해도 적용되는지가 궁금합니다

    • BlogIcon EXYNOA at 2014.04.28 22:11 신고 [edit/del]

      네, 물론 그런식으로 코드를 작성하시면 됩니다. 편한 방법으로 코드를 기술하시어 작업하시면 되겠습니다.

      for i in range(1, 100):
         f = open("data-{0}.data".format(i), 'rb')
         ...

  5. dimebagg at 2014.04.30 13:31 신고 [edit/del]

    답변 감사합니다! 많은 도움이 되었네요 ㅎㅎ

    Reply
  6. version(3.4.1) at 2014.06.04 11:04 신고 [edit/del]

    혹시 제글 지우셧나요?제가 테스트하다가 잘못알아서 지울려고했는데..;

    Reply
  7. 김수희 at 2014.10.13 21:51 신고 [edit/del]

    저가지금 가오스조던 forworld 엘리미네이션 코드를 짜고싶은데요 혹시 강좌나 쪽지남겨주실수있나요?

    Reply
  8. 오류 at 2014.12.28 15:57 신고 [edit/del]

    f = open('setting.txt','r') 이부분에서
    an integer is required(got type str) 이오류가 떠요;;
    뭐하라는 뜻인가요?

    Reply
    • BlogIcon EXYNOA at 2014.12.29 18:24 신고 [edit/del]

      내장 open 함수가 아닌 os 모듈의 open 함수를 사용하시고 계신 것 같습니다. 두번째 매개변수에서 플래그를 받고 있는데, 문자열이 대신 넘어가니 그런 오류가 발생하시는 것 같습니다.

      https://docs.python.org/2/library/os.html#os.open

  9. kim at 2015.01.07 16:16 신고 [edit/del]

    f = open("aaa.txt")
    라고 했을때 aaa.txt 와 같은 폴더 내에 있어야 하는데
    다른 폴더 안에 있는 파일을 읽을때는 어떻게 해야하나요?

    Reply
  10. chang at 2015.04.23 13:03 신고 [edit/del]

    잘 배우고 있습니다만
    프린터로 결과를 출력하려면 어떻게 해야 하는지요?

    Reply
  11. danis0411 at 2016.01.07 12:18 신고 [edit/del]

    >>> f = open('C:\t.txt', 'r')

    Traceback (most recent call last):
    File "<pyshell#1>", line 1, in <module>
    f = open('C:\t.txt', 'r')
    OSError: [Errno 22] Invalid argument: 'C:\t.txt'
    무슨오류죠??

    Reply
  12. dkn1993 at 2016.01.18 01:50 신고 [edit/del]

    안녕하세요 파이썬을 이제야 배우기 시작해서 강의 정말 잘 보고 있습니다!

    위 코드 중

    for i in range(1,10):
    data = "2*%d = %d\n" % (i, 2*i)

    라고 하면 data에 오직 2*9 = 18 밖에 안 쓰이네요 ㅠㅠ
    이건 어떻게 해결해야 할까요

    Reply
    • 지나가다 at 2017.09.26 12:33 신고 [edit/del]

      data =
      문장을 들여쓰기 하시면 됩니다.

      현재는 for 루프가 암것도 안하고 완료된다음
      마지가 값이 i =9 에서 끝이난 상태입니다.

  13. 김아스 at 2016.01.29 10:29 신고 [edit/del]

    FILE을 R모드로 OPEN할때, 해당 파일을 열고 있으면 락이 걸려서 못읽는 사태가 발생하는데 이를 무시하고 강제로 여는 방법은 없을까요? 구글링에도 딱히 안나오네요;;

    Reply
  14. Data at 2016.03.24 13:53 신고 [edit/del]

    잘 배우고 있습니다

    Reply
  15. 살려주세요 at 2017.10.07 16:34 신고 [edit/del]

    제가 RPG를 만들고 있는데 '오류' 분이랑 똑같은 오류가 발생하네요.
    근데 어쩔 수 없이 os를 넣어야 되는데 영어를 잘 못해서..
    어떻게 하면 될까요.. ㅜㅜ

    Reply
    • 살려주세요 at 2017.10.07 16:46 신고 [edit/del]

      앞에 os. 을 붙여보고
      인자 f도 중간에 넣어서
      os.open("파일", f, "r")
      이렇게도 해봤는데 os를 찾을 수 없다네요..
      어떻게 된건지.ㅜ

    • BlogIcon EXYNOA at 2017.10.10 07:45 신고 [edit/del]

      모듈을 import 한 후에 사용해야 합니다.

      예)
      import os
      fd = os.open("file.txt", os.O_RDONLY | os.O_CREAT)

    • 살려주세요 at 2017.10.21 09:43 신고 [edit/del]

      근데 import os 라고 하면 system을 찾을 수 없다는데 어떻게 하죠.. ㅜㅜ

    • 살려주세요... at 2017.10.21 12:20 신고 [edit/del]

      일단 system 문제는 os.system으로 해결했는데 저장할때 system으로 하니까 local variable 'f' referenced before assignment 라고 하네요.. 이건 어떻게 해야 할까요..

submit

티스토리 툴바