DEV Community

nailhae
nailhae

Posted on

[시스템 프로그래밍] 파일 읽기, 쓰기

Reading a file -read(2)

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
Enter fullscreen mode Exit fullscreen mode
  • fd (file descriptor)
    • 읽으려는 파일의 file descriptor
  • buf (buffer)
    • 읽은 내용을 저장할 buffer의 시작 주소
  • count
    • 읽을 byte의 수
  • return: 실제로 읽은 byte의 수
    • 0: 파일의 끝(EOF)에 도달
    • -1: 에러

Writing to a file - write(2)

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
Enter fullscreen mode Exit fullscreen mode
  • fd (file descriptor)
    • 기록려는 파일의 file descriptor
  • buf (buffer)
    • 기록할 내용을 저장된 buffer의 시작 주소
  • count
    • 기록할 byte의 수
  • return: 실제로 기록한 byte의 수
    • -1: 에러

File offset (File position)

  • File operation (e.g., read/write)을 적용할 위치
  • 파일의 시작점부터 현재 위치까지의 vyte 수
  • Read(2)/Write(2) 수행 시, 읽은/기록한 byte 수 만큼 순차적으로 이동

실습

파일 내용 복사

#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    int     rfd;
    int     wfd;
    int     n;
    char    buf[10];

    rfd = open("hello.txt", O_RDONLY);
    if (rfd == -1)
    {
        perror("Open hello.txt");
        exit(1);
    }
    wfd = open("hello.bak", O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (wfd == -1)
    {
        perror("Open hello.bak");
        exit(1);
    }
    n = read(rfd, buf, 6);
    while (n > 0)
    {
        if (write(wfd, buf, n) != n)
            perror("Write");
        n = read(rfd, buf, 6);
    }
    if (n == -1)
        perror("Read");
    closd(rfd);
    closd(wfd);
    return (0);
}
Enter fullscreen mode Exit fullscreen mode

File access methods

  • Sequantial access (순차 접근)
    • File을 record(or bytes) 단위로 순서대로 접근
      • e.g., fgetc()
  • Directed access (직접 접근)
    • 원하는 Block을 직접 접근
      • e.g., lseek(), seek()
  • Indexed access
    • Index를 참조하여, 원하는 block를 찾은 후 데이터에 접근

Moving the file offset - lseek(2)

#include <sys/types.h>
#include <unistd.h>

off_t   lseek(int fd, off_t offset, int whence);
Enter fullscreen mode Exit fullscreen mode
  • fd (file descriptor)
    • 대상 file descriptor
  • offset
    • 이동시킬 byte 수 (양수 or 음수)
  • whence

    • 기준 위치
    • SEEK_SET: 파일의 시작
    • SEEK_CUR: 현재 위치
    • SEEK_END: 파일의 끝
    • 사용 예
      • lseek(fd, 5, SEEK_SET)
        • 파일 시작에서 5번째 byte로 이동
      • lseek(fd, 0, SEEK_END);
        • 파일의 끝으로 이동
      • cur_offset = lseek(fd, 0, SEEK_CUR);
  • return: 이동 후 file offset

    • -1: 에러

Moving the file offset

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    int     fd;
    int     n;
    off_t   start;
    off_t   cur;
    char    buf[256];

    fd = open("linux.txt", O_RDONLY);
    if (fd == -1)
    {
        perror("Open linux.txt");
        exit(1);
    }
    start = lseek(fd, 0, SEEK_CUR);
    n = read(fd, buf, 255);
    buf[n] = '\0';
    printf("Offset start=%d, Read Str=%s, n=%d\n", (int)start, buf, n);
    cur = lseek(fd, 0, SEEK_CUR);
    printf("Offset cur=%d\n", (int)cur);
    start = lseek(fd, 6, SEEK_SET);
    n = read(fd, buf, 255);
    buf[n] = '\0';
    printf("Offset start=%d, Read Str=%s", (int)start, buf);
    close(fd);
    return (0);
}
Enter fullscreen mode Exit fullscreen mode

Page cache & write-Back

  • Page cache
    • In-memory store of recently accessed data from an on-disk filesystem
    • Disk 접근 시간 절약을 위해 kernel 내부적 기법
  • Page write-back
    • Page cache에 변경 된 내용을 disk에 반영하는 것
    • 반영 시기는 kernel이 결정

Synchronizing with disks - fsync(2)

#include <unistd.h>

int fsync(int fd);
Enter fullscreen mode Exit fullscreen mode
  • Page write-back을 강제로 수행
  • fd (file descriptor)
    • 대상 file descriptor
  • return
    • 0: success
    • -1: error

참고

Top comments (0)