Чтение в файле построчно, read () захватывает весь файл - PullRequest
1 голос
/ 17 апреля 2019

У меня проблемы с чтением в файле строка за строкой. Видимо системный вызов read() захватывает весь файл. Я пытаюсь прочитать файл со строками переменной длины, однако я знаю, что длина строки не может превышать SBUFSIZE байтов. Я должен прочитать в каждой строке файла и поместить каждую строку файла в структуру данных. Однако мой подход помещает весь файл одной строкой в ​​структуру данных, что недопустимо. Есть ли измененная версия read(), которая останавливается на символе '\n'?

#define SBUFSIZE 1025

pthread_mutex_t buffer_lock;

void* process_file(void* file_name)
{
    int input_fd;
    /* Temporary buffer, for reading in the files, one line at a time. */
    char buf[SBUFSIZE];
    memset(buf, '\0', SBUFSIZE);

    if ((input_fd = open((char*) file_name, O_RDONLY)) == -1) {
        fprintf(stderr, "Cannot open the file '%s'\n", (char*) file_name);
        pthread_exit((void*) 1);  /* This is my error flag. */
    }

    while (read(input_fd, buf, SBUFSIZE)) {
        int ret;
        printf("|%s|\n", buf);
        while (true) {
            pthread_mutex_lock(&buffer_lock);
            ret = stack_push(buf);
            if (ret == STACK_FULL) {
                pthread_mutex_unlock(&buffer_lock);
                usleep(rand() % 101);
            } else {
                break;
            }
        }
        pthread_mutex_unlock(&buffer_lock);
        memset(buf, '\0', SBUFSIZE);

        if (ret != STACK_SUCCESS) {
            exit(EXIT_FAILURE);
        }
    }

    close(input_fd);
    pthread_exit((void*) 0);  /* This is my good flag. */
}

1 Ответ

1 голос
/ 17 апреля 2019

Вы можете обрабатывать построчно следующим образом:

char buf[SBUFSIZE + 1];
size_t bufsize = 0;

for(;;)
{
    ssize_t nread = read(input_fd, buf + bufsize, SBUFSIZE - bufsize);
    if(nread < 0)
        perror("read failed");

    bufsize += nread;
    if(!bufsize)
        break; // end of file

    const char *eol = memchr(buf, '\n', bufsize);
    if(!eol)
        eol = buf + bufsize++;
    *eol = 0;

    printf("processing line: |%s|\n", buf);
    process_line(buf);

    ++eol;
    bufsize -= eol - buf;
    memmove(buf, eol, bufsize);
}
...