我一直在尝试使用系统调用(read(),write(),open(),close())在unix / linux中进行cp命令的c编程实现。
但是当我通过终端运行我的程序时,将我的程序源代码复制到名称更改的同一目录(源代码大约是300行)
当我打开该输出文件时,它的字符数比原始文件多。
额外的线与200ish线相同。它来自哪里?
这是屏幕截图when compile
这是原始文件(argp.c)末尾附近的源代码。您将看到我如何使用读写方法。
while (count - ind > 1) {
strcpy(cdir, argv[argc-1]);
if (!isFile(cdir)) {
strcat(cdir, basename(arguments.argv[ind]));
}
if (arguments.update) {
stat(cdir,&stDest);
stat(arguments.argv[ind],&stSrc);
if (difftime(stDest.st_mtim.tv_sec, stSrc.st_mtim.tv_sec) > 0 ) {
printf("Destination file is newer\n");
exit(EXIT_FAILURE);
}
}
//open source file
src = open(arguments.argv[ind],O_RDONLY);
//if source file can't be opened
if (src == -1) {
printf("\nError opening file %s errno = %d\n",arguments.argv[ind],errno);
exit(EXIT_FAILURE);
}
//open target file
if (arguments.force) {
//with -f option(default)
tgt = open(cdir, O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
} else {
//with -n option
tgt = open(cdir, O_WRONLY | O_CREAT | O_EXCL , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
}
//if the target file cannot be read or already exist(with -n option)
if (tgt == -1) {
printf("File exist or it's not a file.\nCan't copy.\n");
exit(EXIT_FAILURE);
}
//read source file
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
//if the source file cannot be read
if (pos == -1) {
printf("\nError in reading data from %s\n",arguments.argv[ind]);
}
//close source file
if (close(src) == -1) {
printf("\nError in closing file %s\n",arguments.argv[ind]);
}
//close target file
if (close(tgt) == -1) {
printf("\nError in closing file %s\n",cdir);
}
ind++;
}
if (arguments.verbose) {
printf("Copy successfully!\n");
}
exit(EXIT_SUCCESS);
}
这是复制文件末尾附近的源代码(123.c)
while (count - ind > 1) {
strcpy(cdir, argv[argc-1]);
if (!isFile(cdir)) {
strcat(cdir, basename(arguments.argv[ind]));
}
if (arguments.update) {
stat(cdir,&stDest);
stat(arguments.argv[ind],&stSrc);
if (difftime(stDest.st_mtim.tv_sec, stSrc.st_mtim.tv_sec) > 0 ) {
printf("Destination file is newer\n");
exit(EXIT_FAILURE);
}
}
//open source file
src = open(arguments.argv[ind],O_RDONLY);
//if source file can't be opened
if (src == -1) {
printf("\nError opening file %s errno = %d\n",arguments.argv[ind],errno);
exit(EXIT_FAILURE);
}
//open target file
if (arguments.force) {
//with -f option(default)
tgt = open(cdir, O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
} else {
//with -n option
tgt = open(cdir, O_WRONLY | O_CREAT | O_EXCL , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
}
//if the target file cannot be read or already exist(with -n option)
if (tgt == -1) {
printf("File exist or it's not a file.\nCan't copy.\n");
exit(EXIT_FAILURE);
}
//read source file
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
//if the source file cannot be read
if (pos == -1) {
printf("\nError in reading data from %s\n",arguments.argv[ind]);
}
//close source file
if (close(src) == -1) {
printf("\nError in closing file %s\n",arguments.argv[ind]);
}
//close target file
if (close(tgt) == -1) {
printf("\nError in closing file %s\n",cdir);
}
ind++;
}
if (arguments.verbose) {
printf("Copy successfully!\n");
}
exit(EXIT_SUCCESS);
}
it(EXIT_FAILURE);
}
//read source file
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
//if the source file cannot be read
if (pos == -1) {
printf("\nError in reading data from %s\n",arguments.argv[ind]);
}
//close source file
if (close(src) == -1) {
printf("\nError in closing file %s\n",arguments.argv[ind]);
}
//close target file
if (close(tgt) == -1) {
printf("\nError in closing file %s\n",cdir);
}
ind++;
}
if (arguments.verbose) {
printf("Copy successfully!\n");
}
exit(EXIT_SUCCESS);
}
答案 0 :(得分:0)
无论读取多少,您都无条件地写入完整缓冲区:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
应该是:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, pos) != pos) {
exit(EXIT_FAILURE);
}
}
答案 1 :(得分:0)
您总是尝试读/写BUFFERSIZE
个字节。但是,如果要复制的文件的大小为BUFFERSIZE
,会发生什么?你写的是上次读过的内容。
read
返回读取的字节数,因此每个write
应该尝试写入这个字节数:
代替:
pos = read(src, buffer, BUFFERSIZE);
//write target file
while (pos > 0) {
write(tgt, buffer, BUFFERSIZE);
pos = read(src, buffer, BUFFERSIZE);
}
使用:强>
pos = read(src, buffer, BUFFERSIZE);
//write target file
while (pos > 0) {
write(tgt, buffer, pos);
pos = read(src, buffer, BUFFERSIZE);
}
此处相同,而不是:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
使用:强>
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, pos) != pos) {
exit(EXIT_FAILURE);
}
}