如何解决fread() 和 fwrite() 可以用来复制 jpegs 吗?
我对编程很陌生,我正在尝试编写一个基本程序来复制 jpeg 文件:
#include <stdio.h>
int main (void)
{
FILE *a = fopen("pic1.jpg","r");
FILE *b = fopen("pic2.jpg","w");
fread(a,1,sizeof(a),b);
fwrite(a,b);
fclose(a);
fclose(b);
}
程序确实创建了一个新文件 pic2.jpg
,但是,当我尝试查看它时,我收到错误消息:Invalid or Unsupported Image Format
,所以这让我觉得我可能正在尝试使用它功能不正确。
解决方法
是的,但您没有正确使用它们。
fread(a,1,sizeof(a),b)
表示从 b sizeof(a)
次读取 1 个字节到 FILE *a 中。这可以编译,但没有多大意义。您在使用 fwrite
时犯了类似的错误。
sizeof(a)
获取 FILE *
指针的大小,通常为 8 字节,而不是文件的大小。所以你只读取和写入 8 个字节。
fread
和 fwrite
的第一个参数是读取和写入的缓冲区,这是缺少的关键元素。
首先,始终检查您的文件操作是否有效。如果它们失败,如果文件不存在或无法打开,程序将继续愉快地运行,并且在尝试写入 NULL 时会出现奇怪的错误。
有些系统区分“二进制”和“文本”文件。您必须添加 b
标志以确保它们不会破坏内容。
我还将使用更具描述性的名称,以免混淆。
FILE *in = fopen("pic1.jpg","rb");
if( !in ) {
perror("can't open pic1.jpg for reading");
}
FILE *out = fopen("pic2.jpg","wb");
if( !out ) {
perror("can't open pic2.jpg for writing");
}
现在我们需要分配一个缓冲区来读取和写入。为了获得最佳性能,这应该类似于磁盘的自然块大小。 4096 或 BUFSIZ 常数是不错的选择。我们使用 char
作为字节数组的代理。如果您想花哨,可以使用 uint8_t
,但由于我们只是复制字节,因此没有实际区别。
读入并在循环中写入直到所有内容都被读取。
char buf[BUFSIZ];
size_t bytes_read;
// Read a buffer sized hunk.
while( (bytes_read = fread(buf,sizeof(buf),in)) ) {
// Write the hunk,but only as much as was read.
fwrite(buf,bytes_read,out);
}
fclose(in);
fclose(out);
我们可以在这里使用 sizeof(buf)
只是因为 buf
是一个已知大小的数组。它将返回缓冲区的大小,而不是 char *
指针的大小。
我们必须小心地只写入我们读取的内容,而不是整个缓冲区。否则,如果我们执行 fwrite(buf,out)
并且最后一次读取仅部分填充了缓冲区,我们将打印垃圾。
fread
返回读取的“项目”数,而不是字节数。这是从 waaay 回来的,当时文件更有可能具有固定大小的记录。为了让它返回字节数,我们告诉它每个“项目”是 1 个字节,我们想要 sizeof(buf)
个“项目”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。