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

标签 c system-calls

我只是想使用 readv() 从文件中获取一些数据。但是总是打印垃圾字符。我试图为 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);
        }
    }

提前谢谢你。

最佳答案

您使用 POSIX readv()writev()函数('scatter read' 和 'gather write' — 另见 Wikipedia on Vectored I/O )当您使用文件描述符并且需要将读取分组到不同(非连续)内存位置的集合或从中写入但您想要通过单个函数调用完成读取或写入。

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

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() 允许我在不更改库函数的情况下编写所有内容,并最大化文件上不会有任何交错的机会。 (在上下文中,有第二个进程使用相同的日志文件和相同的打开文件描述,但协议(protocol)是半双工的,因此临时重叠的可能性很小。但是,使用分散/聚集 I/O 将机会最小化的问题。)

我没有记得使用 readv() 的示例,但是当您知道有多个固定大小的数据 block 要读入非连续的内存位置。

关于c - readv和writev的工作流程。使用 readv 和 writev 而不是使用 read 和 write 的所有优点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49188413/

相关文章:

c - 循环未在指定时间内运行

c - 即使链接更多文件后,fstat() st_nlink=1

java - 使用 C/C++ 的 ptrace Java 程序

c - 在 C : Or how to dynamically allocate an array? 中将文件读入 char 数组

c - 在类 UNIX 操作系统上,二进制文件的最少内存使用量是多少?

c++ - 为什么int和float之和是int?

c++ - 在 C、C++ 中通过移位运算符(<<、>>)移位的位

c - 在 Xcode 上编译时出现 (lldb)

go - 在 win7-64 中调用 dll 时,golang syscall 遇到一些问题

c - event_base_dispatch()如何工作?