dup2 + fgets + printf 实现文件拷贝

发布于:2025-02-10 ⋅ 阅读:(56) ⋅ 点赞:(0)

思路

将源文件的内容读取到内存中,然后将这些内容写入到目标文件。 

1: 打开源文件、目标文件

fopen() 以读模式打开源文件。
open ()以写模式打开目标文件。

2: 读取源文件、写入目标文件

fgets ()从源文件中读取内容。
printf ()将内容写入目标文件。
printf 默认写入标准输出。所以用 dup2() 重定向 标准输出到目标文件。

3: 关闭文件

fclose ()关闭源文件
close ()关闭目标文件

代码: 

   // 检查命令行参数数量
    if (argc != 3) {
        fprintf(stderr, "使用方法: %s <源文件> <目标文件>\n", argv[0]);
        return 1;
    }
    
    // 打开源文件,目标文件
	FILE* rf =fopen(argv[1],"r");
	int wfd = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664);//如果文件不存在,它将被创建;如果存在,它将被覆盖。

	// 保存原始的标准输出文件描述符
	int stdout_backup = dup(1);
	// 标准输出重定向到目标文件
	dup2(wfd,1);

	// 读取源文件内容并写入到重定向后的标准输出(即目标文件)
	char buf[2];
	while(fgets(buf,2,rf)!=NULL)//fgets 会读取一行直到换行符或文件结束
	{//fgets读取的每行内容都含换行符,确保换行符也被写入目标文件。
		printf("%c",buf[0]);
	}
	fflush(stdout);

	// 恢复标准输出
	dup2(stdout_backup,1);
    
    // 关闭文件
	fclose(rf);
	close(wfd);

运行结果:

 

升级代码:(做错误处理)

 // 打开源文件
    FILE *rf = fopen(argv[1], "r");
    if (rf == NULL) {
        perror("打开源文件失败");
        return 1;
    }

    // 创建或打开目标文件
    int wfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (wfd == -1) {
        perror("打开目标文件失败");
        fclose(rf);
        return 1;
    }

    // 保存原始的标准输出文件描述符
    int stdout_backup = dup(1);
    if (stdout_backup == -1) {
        perror("备份标准输出失败");
        fclose(rf);
        close(wfd);
        return 1;
    }

    // 将标准输出重定向到目标文件
    if (dup2(wfd, 1) == -1) {
        perror("重定向标准输出失败");
        fclose(rf);
        close(wfd);
        return 1;
    }

    // 读取源文件内容并写入到重定向后的标准输出(即目标文件)
    char buf[1024];
    while (fgets(buf, sizeof(buf), rf) != NULL) {
        printf("%s", buf);
    }
    fflush(stdout);

    // 恢复标准输出
    if (dup2(stdout_backup, 1) == -1) {
        perror("恢复标准输出失败");
        // 不再关闭 rf 和 wfd,因为错误处理可能需要更复杂的逻辑
        return 1;
    }
    close(stdout_backup);

    // 关闭文件
    fclose(rf);
    close(wfd);


网站公告

今日签到

点亮在社区的每一天
去签到