• 2020. 7. 5.

    by. 윈썸지니

    반응형

    지난 포스팅에서는 파이썬 파일 입출력 내용 중 파일 열기에 대해 알아보았습니다.

    이전 글을 참고하세요.

    [IT 이야기 공간/프로그램 언어 및 Database] - 파이썬(Python) 파일 입출력 #1 열기 및 생성하기

     

    파이썬(Python) 파일 입출력 #1 열기 및 생성하기

    이번 포스팅은 프로그램을 개발하다 보면 아주 많이 사용하는 파일 처리에 대해 알아봅니다. 어떤 텍스트 파일을 열어서 읽거나 쓰기를 하는 프로그램을 개발한다고 가정합니다. 처리 순서는 ��

    jinisbonusbook.tistory.com

    이번 포스팅은 파일의 내용을 읽는 방법을 알아봅니다.

    파일을 읽기 또는 쓰기 하려면 무조건 먼저 파일을 open 해야 합니다.

    파일  사용이 끝나면 close() 잊지 말고 해 주세요.

     

    ◆ 파일 읽기

     

    이제 파일을 열어서 파일 내용을 읽어보는 예제를 만들어 봅니다.

    open 함수의 옵션을 알아보았으니 써먹어 봅니다.

     

    먼저 메모장으로 file_test.txt 라는 파일을 만들어서 아래와 같이 문장을 입력하고 저장하였습니다.

    Hello World!
    I am Python
    I like python

    읽기는 read( 글자수 ) 함수를 사용합니다. 글자수를 안 주면 전체를 읽어 옵니다.

    f = open( ‘c:/py_test/file_test.txt’ , mode=‘rt, encoding='utf-8’ )

    f.read ()

    f.close()

     

    IDLE에서 실행해 봅니다.

    >>> f = open( 'c:/py_test/file_test.txt' , mode='rt', encoding='utf-8' )
    >>> f.read ()
    'Hello World!\nI am Python\nI like python'
    >>> f.close()
    >>>

    결과로 파일 전체 내용을 읽었습니다. 그런데 문장이 개행 문자(\n) 를 포함하여 한 덩어리로 읽어 옵니다.

    개행 문자가 포함되어 있으니 print  문을 사용하면 라인 단위로 출력이 될 것 같습니다.

    한번 해 보지요!

    >>> f = open( 'c:/py_test/file_test.txt' , mode='rt', encoding='utf-8' )

    >>> r = f.read()

    >>> r = f.read()

    >>> print(r)

    Hello World!

    I am Python

    I like python

    >>>

    반환값에 r이 포함되어 있으므로 출력해 보면 라인단위로 출력이 됩니다.

    파일 크기가 작다면 read() 를 사용하면 되지만 파일 사이즈가 크다면 한번에 가져오므로 메모리 사용량이 많아져서 그리 좋은 코딩 이라고는 할 수 없습니다.

     

    파일을 하나의 라인씩 읽어오는 함수가 있습니다.

    그전에 read() 에서 괄호안에 숫자를 써 주면 해당 바이트 수 만큼만 읽어 옵니다.

    >>> f.read(10)    # 1
    'Hello Worl'
    >>> f.read(10)     #2
    'd!\nI am Py'
    >>> f.read(10)     #3
    'thon\nI lik'
    >>> f.read(10)      #4
    'e python'
    >>> f.read(10)      #5
    ‘’
    >>>

     

    위의 예제에서 10 바이트씩 4번을 읽었습니다.

     

    자세히 보면 알아서 읽은 자리 다음부터 읽어오는 것을 반복하고

    마지막 4번은 10글자 이지만 남은 글자수가 10보다 작으므로 남은 문자열을 반환해 줍니다.

    그리고 5번은 더 이상 없으므로 오류는 발생하지 않고 빈 값을 반환해 줍니다.

     

    현재 파일의 읽고 있는 위치를 파일 포인터라고 합니다.

    파일을 열면 자동으로 파일의 포인터를 맨 처음으로 해 줍니다. 그리고 읽는 만큼 파일 포인터를 옮겨 줍니다.

    위의 예에서는 그림의 1-> 2 -> 3 ->4 로 옮겨서 현재는 파일 포인터가 마지막에 있습니다.

     

    그럼 또 궁금증이 생기죠? 다시 파일을 읽고 싶을 때는 다시 open 해야 할까요?

    이럴 경우 파일 포인터를 옮겨주는 메소드가 있습니다. seek(포인터위치)  를 사용합니다.

    seek(0) 는 파일의 맨 처음으로 파일 포인터를 옮겨 줍니다.

     

    f.seek( offset, whence)

    • whence : 0 : 처음, 디퐅트, 1 : 현재 파일 포인터 위치, 2 : 파일의 끝
    • offset : whece를 기준으로 파일 포인터 이동, 양수는 뒤쪽으로 이동, 음수는 앞쪽으로 이동

    f.seek(n) : 처음 기준으로 파일의 n byte 이동 , 뒤에 0이 생략된 것임

    f.seek(n, 1) : 현재 위치에서 파일의 n( 양수: 뒤쪽으로, 음수: 앞쪽으로) byte 이동 

    f.seek(n, 2 ) : 파일의 끝에서 파일의 n byte 이동이므로 보통 n은 음수를 사용

    ※ 텍스트 파일은 처음 기준만  seek()  가 됩니다. 즉 whence 를 사용 할 수 없습니다.

    바이너리 파일만 지원합니다.

     

    파일의 현재 포인터 위치를 알고 싶을 경우는 f.tell() 을 사용합니다.

     

    예제를 통해 사용법을 알아봅니다.

    >>> f = open( 'c:/py_test/file_test.txt' , mode='rt', encoding='utf-8' )
    >>> f.read()
    'Hello World!\nI am Python\nI like python'
    >>> f.read()
    ''
    >>> f.seek(0)
    0
    >>> f.read()
    'Hello World!\nI am Python\nI like python’

    ## 파일 포인터는 6번째 바이트로 이동합니다. 다음에 6번째 바이트 부터 읽어 옵니다.
    >>> f.seek(5)
    5
    >>> f.read(2)
    ' W'

    파일을 맨 끝에서 포인터를 이동하려고 하였으나 오류가 발생합니다.

    텍스트 모드 파일로 오픈했기 때문입니다.

    >>> f.seek(-3, 2)
    Traceback (most recent call last):
      File "<pyshell#41>", line 1, in <module>
        f.seek(-3, 2)
    io.UnsupportedOperation: can't do nonzero end-relative seeks

     

    같은 파일을 바이너리 읽기( rb) 모드로 다시 오픈합니다.

    >>> f = open( 'c:/py_test/file_test.txt' , mode='rb' )
    >>> f.tell()
    0
    ## 파일의 현재 포인터 위치를 알려 줍니다.
    >>> f.tell()
    8
    ## 현재 위치에서 뒤쪽으로 3을 이동하여 11이 되었습니다.
    >>> f.seek( 3, 1)
    11
    >>> 
    ## 뒤에서 앞쪽으로 이동하여 10 이동하여 파일 포인터가 30입니다.
    >>> f.seek( -10, 2)
    30
    >>> f.tell()
    30
    ## 바이너리 파일로 읽어서 결과값 앞에 b가 출력됩니다.
    >>> f.read()
    b'ike python'
    >>> f.tell()
    40
    >>> 

    파일 읽기 및 파일 위치 이동에 대해 알아보았습니다.

    파일 한 라인 씩 읽기는 seek()를 설명하느라 본 포스팅이 길어져서 다음 포스팅 작성 예정입니다.

     

    다음 포스팅도 참고해 주세요.

    반응형