본문 바로가기
TIL (Today I Learned)/컴퓨터 시스템(CS)

[CS] File, 파일 읽기/쓰기 #3

by 둥굴프 2022. 12. 13.
이 포스팅은 한국기술교육대학교 김덕수 교수님의 시스템 프로그래밍 (CSE 232)를 참고하여 작성되었습니다.

 

#1 Reading a file - read(2)

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

fd (file descriptor) : 읽으려는 파일의 file descriptor

buf (buffer) : 읽은 내용을 저장할 buffer의 시작 주소

주의사항 : byte 단위를 읽는 것이기 때문에 void 포인터 형태로 넣어야 한다.

count : 읽을 byte의 수

Return : 실제로 읽은 byte의 수

0 = 파일의 끝(EOF)에 도달, -1 = 에러

 

#2 Writing to a file - write(2)

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

 

fd (file descriptor) : 기록하려는 파일의 file descriptor

buf (buffer) : 기록할 내용이 저장할 buffer의 시작 주소

주의사항 : byte 단위를 기록하는 것이기 때문에 void 포인터 형태로 넣어야 한다.

const 상수인 이유는, 버퍼의 내용을 fd에 기록하는 것이기 때문에 버퍼는 수정되어서는 안 된다.

count : 기록할 byte의 수

Return : 실제로 기록한 byte의 수

-1 = 에러

 

File offset (File position)

- File operation (e.g., read/write)을 적용할 위치

- 파일의 시작점부터 현재 위치까지의 byte 수

- Read(2)/Write(2) 수행 시, 읽은/기록한 byte 수만큼 순차적으로 이동

 

File Read &  Write

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

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

    rfd = open("hello.txt", O_RDONLY); // read
    if(rfd == -1) {
        perror("Open hello.txt");
        exit(1);
    }

    wfd = open("hello.bak", O_CREAT | O_WRONLY | O_TRUNC, 0644); // write
    if (wfd == -1) {
        perror("Open hello.bak");
        exit(1);
    }

    while ((n = read(rfd, buf, 6)) > 0)
        if (write(wfd, buf, n) != n) perror("Write");

    if (n == -1) perror("Read");

    close(rfd);
    close(wfd);

    return 0;
}

 

File access methods

(1) Sequential access (순차 접근)

- File을 record(or bytes) 단위로 순서대로 접근

- E.g., fgetc()

 

(2) Directed access (직접 접근)

- 원하는 Block(위치)을 직접 접근

- E.g., lseek(), seek()

 

(3) Indexed access

- Index를 참조하여, 원하는 block을 찾은 후 데이터에 접근

 

#3 Moving the file offset - lseek(2)

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

off_t lseek(int fd, off_t offset, int whence);

fd (file descriptor) : 대상 file descriptor

offset : 이동시킬 byte 수 (양수 or 음수)

whence : 기준 위치

- SEEK_SET : 파일의 시작

- SEEK_CUR : 현재 위치

- SEEK_END : 파일의 

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, n;
    off_t start, 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;
}

 

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이 결정

 

#4 Synchronizing with disks - fsync(2)

#include <unistd.h>

int fsync(int fd);

Page write-back을 강제로 수행

fd (file descriptor) : 대상 file descriptor

Return : 0 = success, -1 = error

 

출처 :&nbsp;https://biriukov.dev/docs/page-cache/2-essential-page-cache-theory/

 

 

긴 글 읽어주셔서 감사드립니다.

22.12.13

댓글