我正在尝试构建一个程序,使用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 bytesn", bytes_read, bytes_written);
if (close (fs)) {
perror("close fs");
return 1;
}
if (close (fd)) {
perror("close fd");
return 1;
}
return 0;
}
问题:假设我运行了与名为file1.txt
的文件相对应的argv[1]程序,并将其复制到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
0 0FFB5F0 0 0 0 0 0C2 0 0 0 0 0 0 0WD4CFFF 0 0VD4CFFF 0 08DC4|8CF8U 0 0C8oA6UE5 0 0@C4|8CF8U 0 0 0 0 0 0 0 0 0 0 C1|8CF8U 0 0`D5CFFF
我怀疑问题的主要原因是buf
阵列的大小不合适。我已经在互联网上查找了解决方案,但什么都找不到。有人能给我一些启发来解决这个问题吗?我试着让buf
或iov_len
变长,但我找不到正确的方法。谢谢大家!
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。