Прочетете всички знаци, написани във FIFO, като използвате системно извикване open().

Имам FIFO тръба, която се отваря в двата края с помощта на open() в режим O_RDWR. В края на четенето read() не чете всички знаци, а по-малко от посочените в извикването. Има ли начин да се гарантира, че всички символи се четат с помощта на open()?

Благодаря предварително

if (p != NULL){

        printf("Inside p not null!\n");

        if((fd = open(p, O_RDWR)) < 0){
            perror("File could not be opened!");
            exit(EXIT_FAILURE);
        }

        //FILE *rdptr = fopen(p,"r");

        memset(buf,0,file_len);
        rc = read(fd, buf, file_len);
        printf("Number of bytes read: %d\n", rc);

        printf("Data detected on FIFO\n");
                buf[rc] = '\0';
                char base[20] = "output.txt";
                char name[20];
                sprintf(name, "%d%s", suffix, base);
        FILE *fptr = fopen(name,"ab+");
        fd_wr = open(name,O_WRONLY);
        charnum = write(fd_wr,buf,rc);
        kill(id_A, SIGKILL);
        //printf("No. of characters written: %d\n",charnum);
                //FD_CLR(fd, &rdfs);
    }

person user3033194    schedule 28.11.2014    source източник
comment
Опитахте ли отново да се обадите на read() за четене на останалите знаци?   -  person saeedn    schedule 28.11.2014
comment
Не, чета го само веднъж. Кодът се добавя в редактираната публикация. Не съм сигурен как да направя това.   -  person user3033194    schedule 28.11.2014
comment
Ако пишете фиксирано количество данни и след това убивате записващия, защо просто не използвате файл вместо това? Изглежда, че тук нямате нужда от FIFO.   -  person nneonneo    schedule 28.11.2014
comment
Не, всъщност всеки писател трябва да пише в отделен FIFO, който се чете от горния процес и след това убива писателя. FIFO е част от изискването. Не мога да променя това.   -  person user3033194    schedule 28.11.2014


Отговори (1)


Първи малък коментар: трябва да използвате O_RDONLY, за да отворите файла: не използвайте повече разрешения от необходимото.

Втори проблем: ако file_len е много голям, възможно е писателят да е блокирал опитите за запис на цялата част от данните (тъй като FIFO може да съдържа само определено количество непрочетени данни). Ако случаят е такъв, тогава read ще прочете само данните, които са били съхранени във FIFO, и веднага ще се върне с всичко, което може да прочете. Това ще позволи на записващия да напише повече байтове, които след това ще бъдат прочетени в следващите read.

Трябва да извършвате циклични четения, коригирайки отместване в буфера, докато не бъдат прочетени всичките file_len байта. Нещо като това:

size_t offset = 0;
while(offset < file_len) {
    rc = read(fd, buf+offset, file_len-offset);
    if(rc < 0) {
        /* handle I/O error or something... */
    } else {
        offset += rc;
    }
}
person nneonneo    schedule 28.11.2014
comment
съжалявам, че не можах да го форматирам правилно, но това ли имаш предвид? - person user3033194; 28.11.2014
comment
No. read ще произведе частичен резултат и трябва да увеличите отместването, за да прочетете повече. (Това е като четене на книга: започвате откъдето сте спрели, а не отначало отново). - person nneonneo; 28.11.2014
comment
С този код се опитвам да отпечатам rc след излизане от цикъла while, но никога не го прави. Изглежда, че цикълът не излиза, може би защото четенето е блокирано или нещо подобно. - person user3033194; 28.11.2014
comment
може би има начин да се промие FIFO? Не знам дали това е правилният термин. - person user3033194; 28.11.2014