字节拷贝程序无法复制.jpg等二进制文件的问题求助
二进制文件复制失败的问题排查与解决
我写了一个简易C程序,目标是复制任意类型的文件(包括.jpg、.png、.mp3、.exe等二进制文件),原理是直接拷贝文件的所有字节序列。但程序复制.txt文件正常,生成的二进制文件却无法被系统打开。
程序基于Windows MingW编译,运行示例:
复制图片到文本文件的命令:
C:\Users\Computer\Desktop>duplicate.exe img.jpg file.txt
生成的file.txt内容(可见二进制字节):
ÿØÿà JFIF ÿÛ C
但执行以下命令复制图片到新图片文件时:
C:\Users\Computer\Desktop>duplicate.exe img.jpg new_img.jpg
生成的new_img.jpg无法被系统识别打开。
附上程序代码:
//The program is just a test, is not a final version, hence the absence of some error handling. #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define MAXBYTE 2500 #define RDWRMAX 1024 int main(int argc, char **argv){ int ifd, ofd, n; char buf[MAXBYTE+1]; if((ifd = open(*++argv, O_RDONLY, 0)) == -1){ fprintf(stderr, "Unable to open '%s'.\n", *argv); exit(EXIT_FAILURE); } if((ofd = open(*++argv, O_WRONLY | O_CREAT, 0)) == -1){ fprintf(stderr, "Unable to open '%s'.\n", *argv); exit(EXIT_FAILURE); } while((n = read(ifd, buf, RDWRMAX)) > 0) write(ofd, buf, n); }
问题原因
- 文件权限参数错误:调用
open创建输出文件时,第三个参数(文件权限位)传了0,这会导致生成的文件权限不合法(比如无读取权限),系统无法正常解析文件内容。POSIX标准中,使用O_CREAT标志时必须指定合法的权限位。 - Windows下的模式转换问题:MingW环境中,
open函数默认可能会采用文本模式处理文件,这会导致二进制数据中的换行符(0x0A)被转换为Windows风格的0x0D0A,破坏二进制文件的原有字节结构,导致文件损坏。
解决方法
- 修正文件权限参数:创建文件时指定合法的权限位,比如
0644(所有者可读可写,其他用户可读)。 - 明确指定二进制模式:在打开文件时添加
O_BINARY标志,强制以二进制模式处理文件,避免文本模式的转换操作。 - 补充文件关闭操作:原代码遗漏了
close调用,可能导致部分数据滞留在缓冲区未写入文件,补充关闭操作可确保所有数据被持久化。
修改后的代码
//The program is just a test, is not a final version, hence the absence of some error handling. #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define MAXBYTE 2500 #define RDWRMAX 1024 int main(int argc, char **argv){ int ifd, ofd, n; char buf[MAXBYTE+1]; // 以二进制模式打开输入文件 if((ifd = open(*++argv, O_RDONLY | O_BINARY, 0)) == -1){ fprintf(stderr, "Unable to open '%s'.\n", *argv); exit(EXIT_FAILURE); } // 以二进制模式创建输出文件,指定合法权限并清空原有内容 if((ofd = open(*++argv, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644)) == -1){ fprintf(stderr, "Unable to open '%s'.\n", *argv); exit(EXIT_FAILURE); } while((n = read(ifd, buf, RDWRMAX)) > 0) write(ofd, buf, n); // 关闭文件,确保数据写入磁盘 close(ifd); close(ofd); }
额外说明
O_TRUNC标志确保如果目标文件已存在,会先清空原有内容再写入,避免新旧内容混杂导致文件损坏。
内容的提问来源于stack exchange,提问作者KmerPadreDiPdor
相关产品推荐
相关产品推荐

