Post

File i/o

๐Ÿ“‹File i/o

ํŒŒ์ผ์„ ์—ด๊ณ , ์ƒ์„ฑํ•˜๊ณ , ์ฝ๊ณ , ์“ฐ๊ณ , ๋‹ซ๋Š” ๊ณผ์ •

nano openfile.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h> // ํ‘œ์ค€ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณต
#include <stdlib.h> // ์ผ๋ฐ˜์ ์ธ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณต
#include <fcntl.h> // ํŒŒ์ผ ์ œ์–ด ๊ด€๋ จ ์ƒ์ˆ˜๋“ค๊ณผ ํŒŒ์ผ ์ œ์–ด ํ•จ์ˆ˜๋“ค์„ ์ •์˜
#include <unistd.h> // Unix ํ‘œ์ค€ ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณต
#include <string.h> // ๋ฌธ์ž์—ด ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณต

int main() {
    const char *path = "example.txt"; // ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ path์— ์ €์žฅํ•œ๋‹ค

    // ํŒŒ์ผ ์—ด๊ธฐ ์‹œ๋„ : ์ฝ๊ธฐ&์“ฐ๊ธฐ ๊ถŒํ•œ์œผ๋กœ ์—ด๊ณ , ํŒŒ์ผ์ด ์—†์„ ๊ฒฝ์šฐ ์ƒ์„ฑ, ์†Œ์œ ์ž์— ๋Œ€ํ•œ ์ฝ๊ธฐ&์“ฐ๊ธฐ ๊ถŒํ•œ ์„ค์ •
    int file_descriptor = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 
    if (file_descriptor == -1) { // ์‹คํŒจํ•  ๊ฒฝ์šฐ -1 ๋ฐ˜ํ™˜
        perror("open");
        exit(EXIT_FAILURE); // exit(0)์€ ์ •์ƒ์  ์ข…๋ฃŒ, exit(EXIT_FAILURE)์€ ์˜ค๋ฅ˜๋กœ ์ข…๋ฃŒ
    }

    // ํŒŒ์ผ์— ์“ฐ๊ธฐ
    char *message = "Hello, Unix!";
    write(file_descriptor, message, strlen(message)); // ๋ฌธ์ž์—ด์„ ํŒŒ์ผ์— ์“ฐ๊ธฐ

    // ํŒŒ์ผ์—์„œ ์ฝ๊ธฐ
    char buffer[100]; // ๋ฌธ์ž ๋ฐฐ์—ด ์„ ์–ธ
    lseek(file_descriptor, 0, SEEK_SET);  // ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ํŒŒ์ผ ์‹œ์ž‘์œผ๋กœ ์ด๋™
    read(file_descriptor, buffer, 100); // ์ตœ๋Œ€ 100๋ฐ”์ดํŠธ๊นŒ์ง€ ์ฝ๊ธฐ

    printf("Read from file: %s\n", buffer); // ์ฝ์–ด์˜จ ๋ฐ์ดํ„ฐ ์ถœ๋ ฅ

    // ํŒŒ์ผ ๋‹ซ๊ธฐ
    close(file_descriptor);

    return 0;
}

gcc -o openfile openfile.c

./openfile

์ถ”๊ฐ€ ์„ค๋ช…

const char *path = "example.txt";

ํŒŒ์ผ์˜ ๊ฒฝ๋กœ, ์ฆ‰ โ€œexample.txtโ€ ๋ฌธ์ž์—ด์˜ ์‹œ์ž‘ ์ฃผ์†Œ๋ฅผ path์— ์ €์žฅํ•œ๋‹ค.

open()

open(์—ด๋ ค๋Š” ํŒŒ์ผ์˜ ๊ฒฝ๋กœ ๋˜๋Š” ์ด๋ฆ„, ํŒŒ์ผ์„ ์–ด๋–ป๊ฒŒ ์—ด์ง€๋ฅผ ์ง€์ •ํ•˜๋Š” ํ”Œ๋ž˜๊ทธ, ํŒŒ์ผ์„ ์ƒ์„ฑํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ)

  • O_RDONLY: ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ํŒŒ์ผ ์—ด๊ธฐ.
  • O_WRONLY: ์“ฐ๊ธฐ ์ „์šฉ์œผ๋กœ ํŒŒ์ผ ์—ด๊ธฐ.
  • O_RDWR: ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ชจ๋“œ๋กœ ํŒŒ์ผ ์—ด๊ธฐ.
  • O_CREAT: ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ.
  • O_APPEND: ํŒŒ์ผ ๋์— ์“ฐ๊ธฐ ์œ„ํ•ด ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์ด๋™.
  • O_TRUNC: ํŒŒ์ผ์ด ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ํŒŒ์ผ ํฌ๊ธฐ๋ฅผ 0์œผ๋กœ ์ž˜๋ผ๋‚ด๊ธฐ.

char *message = "Hello, Unix!"

โ€œHello, Unix!โ€๋ผ๋Š” ๋ฌธ์ž์—ด์˜ ์ฃผ์†Œ๋ฅผ message์— ์ €์žฅํ•œ๋‹ค.

write()

write(๋ฐ์ดํ„ฐ๋ฅผ ์“ธ file descriptor, ์“ธ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ธด ๋ฒ„ํผ์˜ ํฌ์ธํ„ฐ, ์“ธ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ (๋ฐ”์ดํŠธ ๋‹จ์œ„))
-> ๊ฒฐ๊ณผ๊ฐ’์€ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

lseek()

lseek(file descriptor, offset, whence) : ์ƒˆ๋กœ์šด ํŒŒ์ผ ํฌ์ธํ„ฐ์˜ ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜

  • offset: ์˜คํ”„์…‹ ๊ฐ’. ์ด ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํŒŒ์ผ ํฌ์ธํ„ฐ์˜ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ
  • whence: ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ธฐ์ค€
    • SEEK_SET: ํŒŒ์ผ์˜ ์‹œ์ž‘์„ ๊ธฐ์ค€์œผ๋กœ ์˜คํ”„์…‹์„ ์„ค์ •
    • SEEK_CUR: ํ˜„์žฌ ํŒŒ์ผ ํฌ์ธํ„ฐ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์˜คํ”„์…‹์„ ์„ค์ •
    • SEEK_END: ํŒŒ์ผ์˜ ๋์„ ๊ธฐ์ค€์œผ๋กœ ์˜คํ”„์…‹์„ ์„ค์ •

read()

read(file descriptor, ์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋ฒ„ํผ์˜ ํฌ์ธํ„ฐ, ์ฝ์„ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ(๋ฐ”์ดํŠธ ๋‹จ์œ„))

๋ณต์Šตํ•˜๋ฉฐ ์•Œ๊ฒŒ๋œ ๊ฒƒ๋“ค.

file์ด open์ด๋‚˜ creat๋กœ file descriptor๊ฐ€ ์ƒˆ๋กœ ํ• ๋‹น๋˜๊ณ , read๋‚˜ writeํ•  ๋•Œ ์ด๋ฅผ ์ด์šฉํ•œ๋‹ค. ์ด๋•Œ, user๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ํŒŒ์ผ์˜ file descriptor๋Š” 3์ด ๋˜๋Š”๋ฐ, ๊ทธ ์ด์œ ๋Š” ๊ธฐ๋ณธ ์„ธํŒ…์œผ๋กœ

  • 0 -> ํ‘œ์ค€ ์ž…๋ ฅ (stdin)
  • 1 -> ํ‘œ์ค€ ์ถœ๋ ฅ (stdout)
  • 2 -> ํ‘œ์ค€ ์˜ค๋ฅ˜ (stderr)

์˜ file descriptor๊ฐ€ ํ• ๋‹น๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฉ”๋ชจ๋ฆฌ์—์„œ file descriptor๊ฐ€ ํ• ๋‹น๋จ์œผ๋กœ์จ, ์‹œ์Šคํ…œ์˜ ํŒŒ์ผ๊ณผ ์—ฐ๊ฒฐ๋œ๋‹ค.

open()์˜ flag ์ค‘์— O_EXCL์ด ๊ต‰์žฅํžˆ ๋…ํŠนํ•œ๋ฐ, ํŒŒ์ผ์ด ์กด์žฌํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ๋‚ด๊ณ  open์€ ์‹คํŒจํ•˜๋ฉด์„œ return๊ฐ’์€ -1์ด ๋œ๋‹ค. ์ด๊ฒŒ ์กด์žฌํ•˜๋Š” ์ด์œ ๋Š” ํŒŒ์ผ์ด ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์— ์‹คํŒจ์‹œํ‚ด์œผ๋กœ์จ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹ ๋ขฐ์„ฑ์„ ํ™•๋ณดํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>

#define LOCKFILE "lockfile"
#define DELAY 100000000

void delay(void)
{
        int i;
        for (i=0;i<DELAY;i++);
}

int main(void)
{
        int fd, i;

        while((fd = open(LOCKFILE, O_WRONLY | O_CREAT | O_EXCL, 0644)) < 0) {
                if (errno != EEXIST) {  //ํŒŒ์ผ์ด ์žˆ์Œ์œผ๋กœ์จ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜(EEXIST)๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด,
                        perror("open"); 
                        exit(1); // ์ข…๋ฃŒ
                } // ํ•˜์ง€๋งŒ, ํŒŒ์ผ์ด ์žˆ์Œ์œผ๋กœ์จ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜(EEXIST)๋ผ๋ฉด, ๊ณ„์† ๋ฌดํ•œ๋ฃจํ”„..
        }
        for (i = 'a'; i <= 'z'; i++) {
                putchar(i);
                fflush(stdout);
                delay();
        }
        printf("\n");
        close(fd); // ํŒŒ์ผ ์‚ญ์ œ
        unlink(LOCKFILE);

        return 0;
}

์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  a-z๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ  ์žˆ์„ ๋•Œ, ctrl-c๋ฅผ ๋ˆ„๋ฅด๋ฉด ์‹คํ–‰์ด ๋ฉˆ์ถ”๊ณ  ์ข…๋ฃŒ๋˜๋ฉด์„œ, lockfile์ด ์‚ญ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค. ํŒŒ์ผ์ด ์žˆ์Œ์œผ๋กœ์จ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜, ์ฆ‰ EEXIST ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•จ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์ƒํƒœ์—์„œ ๋‹ค์‹œ ํŒŒ์ผ์„ ์‹คํ–‰์‹œํ‚ค๋ฉด ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์ ธ์„œ ํŒŒ์ผ์ด ์ข…๋ฃŒ๋˜์ง€ ์•Š๊ณ  ๊ณ„์† ์ง„ํ–‰๋œ๋‹ค.

This post is licensed under CC BY 4.0 by the author.