【问题标题】:Unwanted characters when copying file using scatter/gather I/O (readv/writev)使用 scatter/gather I/O (readv/writev) 复制文件时不需要的字符
【发布时间】:2021-01-05 00:57:10
【问题描述】:

我正在尝试构建一个程序,以使用 readv() 和 writev() 将现有内容从现有文件复制到新文件。 这是我的代码:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[]) 
{
    int fs, fd; 

    ssize_t bytes_read, bytes_written;
    char buf[3][50]; 
    int iovcnt;
    struct iovec iov[3];
    int i;
    fs = open(argv[1], O_RDONLY); 
    if (fs == -1) {
        perror("open");
        return -1;
    }
    fd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); 
    if (fd == -1) {
        perror("open");
        return 1;
    }

    for(i = 0; i < 3; i++) {
        iov[i].iov_base = buf[i];
        iov[i].iov_len = sizeof(buf[i]);
    }

    iovcnt = sizeof(iov) / sizeof(struct iovec);


    if ((bytes_read=readv(fs, iov, iovcnt)) != -1)
        if ((bytes_written=writev(fd, iov, iovcnt)) == -1)
            perror("error writev");
    printf("read: %ld bytes, write: %ld bytes\n", bytes_read, bytes_written);
    if (close (fs)) {
        perror("close fs");
        return 1;
    }
    if (close (fd)) {
        perror("close fd");
        return 1;
    }
    return 0;
}

问题:假设我使用 argv[1] 运行程序,对应于名为 file1.txt 的文件并将其复制到 argv[2],假设它被称为 hello.txt。 这是file1.txt的内容:

Ini adalah line pertamaS
Ini adalah line kedua
Ini adalah line ketiga

当我运行程序时,在 argv[2] 中指定的新创建文件被不需要的字符填充,例如 \00。 运行程序后输出:

Ini adalah line pertamaS
Ini adalah line kedua
Ini adalah line ketiga
\00\00\FF\B5\F0\00\00\00\00\00\C2\00\00\00\00\00\00\00W\D4\CF\FF\00\00V\D4\CF\FF\00\00\8D\C4|\8C\F8U\00\00\C8o\A6U\E5\00\00@\C4|\8C\F8U\00\00\00\00\00\00\00\00\00\00 \C1|\8C\F8U\00\00`\D5\CF\FF

我怀疑问题的主要原因是 buf 数组的大小不合适。我已经在互联网上查找解决方案,但找不到任何东西。谁能给我一些启示来解决这个问题?我试图将bufiov_len 设置为可变长度,但我找不到正确的方法。谢谢大家!

【问题讨论】:

  • 我不明白。为什么当你从上一行有 'bytes_read' 时要写 'iovcnt' 字节?

标签: c operating-system filesystems


【解决方案1】:

readv() 使用由每个.iov_len 驱动的字节数,并且对任何内容都没有特殊处理(如换行)。原贴中的readv() 传递了一个由 (3) 个struct iovec 组成的数组,每个.iov_len 设置为50。readv() 成功后,本地buf[3][50] 的内容将是:

buf[0] : 输入文件的前 50 个字节
buf[1] :输入文件的下 20 个字节,然后是 30 个字节的未初始化/剩余堆栈数据
buf[2] :另外 50 字节的未初始化/剩余堆栈数据

writev() 重用相同的 struct iovec 数组,所有 (3) .iov_len 与 50 保持不变,并按预期写入 150 个字节。输出文件的内容包含从输入文件复制的前 70 个字节和 80 个字节的剩余堆栈数据。如果在调用 readv() 之前清除了本地 buf,则输出文件将包含尾随 NULL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 2014-05-25
    • 2012-03-09
    • 2022-07-22
    相关资源
    最近更新 更多