파일 처리하기

이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07

파일 읽기 쓰기

다음은 os 패키지에서 제공하는 파일 열기 함수와 파일 포인터 설정 함수입니다.

  • func OpenFile(name string, flag int, perm FileMode) (file *File, err error): 파일 플래그, 파일 모드를 지정하여 파일 열기
  • func (f *File) Seek(offset int64, whence int) (ret int64, err error): 파일을 읽거나 쓸 위치로 이동

os.OpenFile 함수를 사용하여 읽기/쓰기 모드로 파일을 연 뒤 파일을 읽고 써보겠습니다.

package main

import (
	"fmt"
	"os"
)

func main() {
	file, err := os.OpenFile(
		"hello.txt",
		os.O_CREATE|os.O_RDWR|os.O_TRUNC, // 파일이 없으면 생성,
                                                  // 읽기/쓰기, 파일을 연 뒤 내용 삭제
		os.FileMode(0644))                // 파일 권한은 644
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close() // main 함수가 끝나기 직전에 파일을 닫음

	n := 0
	s := "안녕하세요"
	n, err = file.Write([]byte(s)) // s를 []byte 바이트 슬라이스로 변환, s를 파일에 저장
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(n, "바이트 저장 완료")

	fi, err := file.Stat() // 파일 정보 가져오기
	if err != nil {
		fmt.Println(err)
		return
	}

	var data = make([]byte, fi.Size()) // 파일 크기만큼 바이트 슬라이스 생성

	file.Seek(0, os.SEEK_SET) // Write 함수로 인해 파일 읽기/쓰기 위치가
                                  // 이동했으므로 file.Seek 함수로 읽기/쓰기 위치를
                                  // 파일의 맨 처음(0)으로 이동
	n, err = file.Read(data)  // 파일의 내용을 읽어서 바이트 슬라이스에 저장
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(n, "바이트 읽기 완료")
	fmt.Println(string(data)) // 문자열로 변환하여 data의 내용 출력
}

실행 결과

15 바이트 저장 완료
15 바이트 읽기 완료
안녕하세요

os.OpenFile 함수는 파일 이름, 플래그, 파일 모드를 받습니다. 먼저 플래그의 종류는 다음과 같습니다.

플래그 설명
os.O_RDONLY 읽기 전용으로 파일을 엽니다.
os.O_WRONLY 쓰기 전용으로 파일을 엽니다.
os.O_RDWR 읽기, 쓰기를 모두 할 수 있도록 파일을 엽니다.
os.O_APPEND 파일을 저장했을 때 끝부분에 내용을 추가합니다.
os.O_CREATE 파일이 없으면 파일을 새로 생성합니다. 파일이 있으면 파일을 해당 파일을 엽니다.
os.O_EXCL 파일이 없을 때만 새로 생성하며 O_CREATE와 함께 사용합니다.
os.O_SYNC 동기(Synchronous) I/O를 사용합니다.
os.O_TRUNC 파일이 있다면 파일을 연 뒤 내용을 삭제합니다.

표 49-1 파일 플래그

플래그는 OR(|) 연산자를 사용하여 조합할 수 있습니다. 여기서는 os.O_RDWR로 읽기, 쓰기를 하고, os.O_CREATE로 파일이 없으면 파일을 생성하고, os.O_TRUNC로 파일이 있을 때는 파일을 연 뒤 내용을 삭제합니다. 그리고 파일 모드는 유닉스/리눅스 형식의 권한(Permission)을 지정합니다. 여기서는 os.FileMode 타입으로 0644를 지정했습니다.

file.Write 함수로 파일에 문자열을 저장합니다. 그리고 다시 file.Stat 함수로 파일 크기를 구해와서 슬라이스를 생성합니다.

파일을 읽기 전에 file.Read, file.Write 함수로 파일을 읽거나 쓰면 해당 크기만큼 읽기/쓰기 위치(Offset)가 이동합니다. 따라서 앞에서 file.Write 함수로 파일에 내용을 저장했으므로 Offset이 15바이트만큼 앞으로 이동했습니다. 파일을 처음부터 읽으려면 file.Seek(0, os.SEEK_SET)처럼 파일 읽기/쓰기 위치를 초기화해줍니다.

file.Seek 함수에서 첫 번째 매개변수는 offset(바이트)이며 두 번째 매개변수는 기준점입니다. 다음은 설정할 수 있는 기준점입니다.

  • os.SEEK_SET: 파일의 맨 처음을 기준으로 합니다.
  • os.SEEK_CUR: 현재 읽기/쓰기 offset 값을 기준으로 합니다.
  • os.SEEK_END: 파일의 맨 끝을 기준으로 합니다.

file.Seek(0, os.SEEK_SET)이면 파일의 맨 처음부터 0바이트이므로 파일의 맨 앞이 됩니다. 그리고 file.Read 함수로 파일의 내용을 읽습니다.

유닉스/리눅스의 파일 권한
유닉스/리눅스 파일 권한은 세 부분으로 구성되어 있습니다.

  • 파일 소유자(User)
  • 파일 그룹(Group)
  • 파일에 권한이 없는 소유자(Others)

여기서 읽기, 쓰기, 실행 권한을 설정할 수 있습니다.

  • 읽기(Read, r): 4
  • 쓰기(Write, w): 2
  • 실행(Execute, x): 1

파일 권한이 0644라면 소유자는 읽고 쓸 수 있으며(6=4+2) 그룹과 권한이 없는 소유자는 읽기(4)만 할 수 있습니다. 처음 0은 Sticky bit, SetUID, SetGID 중 어떤 것도 사용하지 않는 설정입니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

01 June 2015