C语言 可以读取()和fwrite()被用来复制jpeg ?



我对编程很陌生,我正试图写一个基本的程序来复制一个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, 1, sizeof(a), b);

fclose(a);
fclose(b);
}

程序确实创建了一个新文件pic2.jpg,然而,当我试图查看它时,我收到错误消息:Invalid or Unsupported Image Format,因此这使我认为我可能试图错误地使用此函数。

是的,但是你没有正确使用它们。

fread(a, 1, sizeof(a), b)表示从bsizeof(a)次读取1字节到FILE *a。这可以编译,但没有多大意义。你在fwrite上犯了类似的错误。

sizeof(a)获取FILE *指针的大小,通常为8字节,而不是文件的大小。所以你只读取和写入8个字节。

freadfwrite的第一个参数是用于读写的缓冲区,这是缺少的关键元素。


首先,总是检查您的文件操作是否工作。如果它们失败,如果文件不存在或无法打开,程序将继续愉快地运行,当它试图写入NULL时,您将得到奇怪的错误。

有些系统会区分"binary"one_answers";text"文件。你必须添加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或bufsize常数都是不错的选择。我们使用char作为字节数组的代理。如果你想花哨一点,你可以使用uint8_t,但因为我们只是复制字节,所以没有实际的区别。

读入它,然后循环从它开始写,直到所有内容都被读完。

char buf[BUFSIZ];
size_t bytes_read;
// Read a buffer sized hunk.
while( (bytes_read = fread(buf, 1, sizeof(buf), in)) ) {
// Write the hunk, but only as much as was read.
fwrite(buf, 1, bytes_read, out);
}
fclose(in);
fclose(out);

我们可以在这里使用sizeof(buf),因为buf是一个已知大小的数组。它将返回缓冲区的大小,而不是char *指针的大小。

我们必须注意只写和读一样多的内容,而不是整个缓冲区。否则,如果我们执行fwrite(buf, 1, sizeof(buf), out),并且最后一次读取只部分填充了缓冲区,我们将打印垃圾。

fread返回"item "读取,而不是字节数。这是从很久以前开始的,那时文件更可能有固定大小的记录。为了让它返回字节数,我们告诉它each "item"为1字节,我们想要sizeof(buf)"item "


  • 从文件中读
  • 写入文件

最新更新