c - diff cmd,二进制文件 x 和 y 不同

标签 c file-io diff pipe

我有一个程序将两个文件作为参数。第一个文件将被复制到第二个文件中。该程序分为 2 个 child ,第一个 child 读取文件并将其通过管道传递给另一个 child ,然后另一个 child 将其写入文件。这两个文件最终应该是相同的。

当我运行 diff 比较这两个文件时,出现以下错误:

virtual@ubuntu:~/Documents/OSprojects$ ./parent test.txt test2.txt
virtual@ubuntu:~/Documents/OSprojects$ cat test.txt
123456789112233445566778899
virtual@ubuntu:~/Documents/OSprojects$ cat test2.txt
123456789112233445566778899
virtual@ubuntu:~/Documents/OSprojects$ diff test.txt test2.txt
Binary files test.txt and test2.txt differ
virtual@ubuntu:~/Documents/OSprojects$ 

如您所见,它们是相同的,但 diff 打印出它们是不同的。显然,这只是我对 diff cmd 不了解的地方。任何帮助将不胜感激。

我相信出于某种原因,我创建的文件是二进制文件,而第一个文件不是,但我不知道为什么它是二进制文件。我相信这可能与这行代码有关:

    write(1, buf, BUF_SIZE);            //write to buffer
    memset(buf, '\0', BUF_SIZE);

在其中一个 child 中,这是写入缓冲区,然后我正在清除缓冲区。我是否错误地清除了缓冲区?

这是 cat -e 的结果:

virtual@ubuntu:~/Documents/OSprojects$ cat -e test2.txt
123456789112233445566778899$
^@^@^@^@virtual@ubuntu:~/Documents/OSprojects$

这是 cmp 的结果:

virtual@ubuntu:~/Documents/OSprojects$ cmp test.txt test2.txt
cmp: EOF on test.txt
virtual@ubuntu:~/Documents/OSprojects$ 

我相信这是我的问题,我怎样才能清除那个缓冲区,这样它就不会在最后抛出那些?

我的所有代码::

家长:

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUF_SIZE 16

void exitWithError(char* errorMsg, int exitWith);       //generic error out function
void launch_writer(const char* pathname, char* const argv[], int pfd[]);    
void launch_reader(const char* pathname, char* const argv[], int pfd[]);   

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

//making the pipe
int pfd[2];
if(pipe(pfd) == -1) //test pipe creation
    exitWithError("PIPE FAILED", 1);

//forking
pid_t reader_child_pid;
pid_t writer_child_pid;

//args for each fork
char *args_1[] = {"reader", argv[1], (char *) 0};
char *args_2[] = {"writer", argv[2], (char *) 0};

if((writer_child_pid = fork()) == -1) {
    exitWithError("WRITER FORK FAILED", 1);
}
else if (writer_child_pid == 0) {       //first child comes here
    launch_writer("./writer", args_2, pfd);
}
else if ((reader_child_pid = fork()) == -1) {
    exitWithError("READER FORK FAILED", 1);
}
else if (reader_child_pid == 0) {       //second child comes here
    launch_reader("./reader", args_1, pfd);
}

//parent picks up here

//close off pipe from parents end
close(pfd[0]);
close(pfd[1]);


//wait for all processes to exit before ending
for(;;) {
    if(wait(NULL) == -1){
        if(errno == ECHILD)
            exit(0);
        else {
            exitWithError("WAIT ERROR", 1);
        }
    }
}
}

void exitWithError(char* errorMsg, int exitWith) {
perror(errorMsg);
exit(exitWith);
}

void launch_writer(const char* pathname, char* const argv[], int pfd[]) {
dup2(pfd[0], 0);
close(pfd[1]);
close(pfd[0]);
execve(pathname, argv, NULL);
perror("execve failed");
}

void launch_reader(const char* pathname, char* const argv[], int pfd[]) {
dup2(pfd[1], 1);
close(pfd[1]);
close(pfd[0]);
execve(pathname, argv, NULL);
perror("execve failed");
}

child 1:

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE 16

int main(int argc, char* argv[]){
//Opens file to be read from
int inFile = open(argv[1], O_RDONLY);

//declaring variables
char buf[BUF_SIZE]; //temp hold whats read/written
int read_test;      //check if EOF
for(;;) {
    read_test = read(inFile, buf, BUF_SIZE);    //read from file
    if(read_test == 0) //eof
        break;
    write(1, buf, BUF_SIZE);            //write to buffer
    memset(buf, '\0', BUF_SIZE);
}
close(inFile);
exit(0);
}

child 2:

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define BUF_SIZE 16

int main(int argc, char* argv[]){
//Opens a file for reading/writing, if exists then truncates, otherwise makes new one
//with correct permissions
int wri_inFile = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR);
if(wri_inFile == -1)
    perror("ERROR OPENING FILE");

//declaring variables
char buf[BUF_SIZE];  //to store what is read in/written out
int read_test;      //test if EOF
for(;;) {
    read_test = read(0, buf, BUF_SIZE); //read from buffer
    if(read_test == 0) //eof
        break;
    write(wri_inFile, buf, BUF_SIZE);   //write to file

}
close(wri_inFile);
exit(0);
}

最佳答案

您不检查(和使用)读取的数据长度。因此,您的数据会被垃圾填满。

应该有实际的数据字节读取(read_test):

read_test = read(0, buf, BUF_SIZE); //read from buffer
if(read_test == 0) //eof
    break;
write(wri_inFile, buf, BUF_SIZE);   //write to file
-----------------------^^^^^^^^

另一个 child 也是如此。您还应该检查错误情况。

关于c - diff cmd,二进制文件 x 和 y 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7374867/

相关文章:

python - 从 Python 调用 C 函数

linux - 如何在空行上拆分带有文本内容的变量

git - 如何区分 ansible vault 的变化?

GitHub - 为什么两行被标记为不同而没有任何明显差异?

java - JNA:指向字符的指针**

c - 如何在 gwan c 脚本中嵌入 perl 脚本?

c - 实现 2D split() 函数

java - FileInputStream.available 会愚弄我吗?

java - 随机化文本文件以避免树不平衡

bash - unix diff 并排结果?