readv和writev的工作流程。使用 readv 和 writev 而不是使用 read 和 write 的所有优点是什么?

Working flow of readv and writev. What are all the advantages of using readv and writev instead of using the read and write?

我只是想使用 readv() 从文件中获取一些数据。但是总是打印垃圾字符。我试图将 space 分配给 iovec.iov_base 但没有成功。我什至想到了为什么要使用 readv 函数而不是坚持使用更简单和可读性更高的 read 函数。我现在很困惑知道需要 readv 和 writev 函数。

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<unistd.h>
    #include<fcntl.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/uio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #define MAX 50000
    int main()
    {
        struct iovec data[2];
        int i=0,fd;
        for(i=0; i<3 ; i++ )  {
            data[i].iov_len=MAX;
            data[i].iov_base=(char*) malloc(MAX); //if this line is in comment, segmentation fault will occur. 
            /* data[i].iov_base=(char*) malloc(0); //This is also working ?*/
        }
        fd=open("/tmp/test",O_RDWR);
        if(fd==-1){
            printf("can't open the input file\n");
            return 1;
        }
        readv(fd,data,3);
        for(i=0; i<2 ; i++ )  {
            printf("((%s))\n",(char*)data[i].iov_base);
        }
    }

提前致谢。

当您使用文件描述符并需要对不同 (non-contiguous) 内存位置的集合的读取或写入进行分组时,您可以使用 POSIX readv() and writev() functions ('scatter read' and 'gather write' — see also Wikipedia on Vectored I/O),但是您希望通过单个函数调用完成读取或写入。

例如,我有一个程序需要记录一些控制数据和一些二进制数据的 hex-dump,但它想确保其写入是原子的。所以,我有这样的功能:

static void log_message(int log_fd, const char *elapsed, const char *tag, const char *buffer, ssize_t nbytes)
{
    char hdrbuff[64];
    struct iovec vector[3];
    const char *data = format_image(buffer, nbytes);

    snprintf(hdrbuff, sizeof(hdrbuff), "%s %s %6ld\n", elapsed, tag, (long)nbytes);

    vector[0].iov_base = hdrbuff;
    vector[0].iov_len  = strlen(hdrbuff);
    vector[1].iov_base = CONST_CAST(char *, data);
    vector[1].iov_len  = strlen(data);
    vector[2].iov_base = "\n";
    vector[2].iov_len  = 1;
    if (writev(log_fd, vector, 3) <= 0)
        err_syserr("Failed to write log entry (%s: %ld)\n", tag, (long)nbytes);
}

需要写换行符有点麻烦,但是 format_image() 函数不能添加杂散的换行符。 (它是在别处使用的库函数,如果它添加一个额外的换行符,其他用途将被破坏。)但是,writev() 允许我在不更改库函数的情况下编写所有内容,并最大限度地提高了获胜的机会' 是文件上的任何交错。 (在上下文中,有第二个进程使用相同的日志文件和相同的打开文件描述,但协议是 half-duplex,因此只有很小的时间重叠的机会。但是,使用 scatter/gather I/O 将出现问题的可能性降到最低。)

我记得没有使用 readv() 的示例,但是当您知道有多个固定大小的数据块要读入 non-contiguous 时,您会使用它内存位置。