为什么 fgets 不能从 popen 流中获取所有字节
Why fgets cannot get all bytes from a popen stream
我编译了以下代码 运行:
$ ./run_curl 'http://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz'
.
但是我无法获取要下载的文件的完整字节。为什么?
我使用 curl --silent 'http://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz' > a.tgz
会得到完整的字节。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 512
void download_pkg(const char* url)
{
char content[SIZE] = {0};
FILE *fp = NULL;
char cmd[255] = {0};
FILE *fp_download = fopen("a.tgz", "w");
sprintf(cmd, "curl --silent '%s'", url);
fp = popen(cmd, "r");
while(fgets(content, SIZE - 1, fp) != NULL) {
fputs(content, fp_download);
}
fclose(fp_download);
pclose(fp);
return;
}
int main(int argc, char *argv[])
{
download_pkg(argv[1]);
return 0;
}
编辑:
根据 Jonathan Leffler 的 ,问题通过以下代码解决:
int size_read = 0;
while((size_read = fread(content, sizeof(char), SIZE - 1, fp)) > 0) {
fwrite(content, sizeof(char), size_read, fp_download);
}
gzipped tar 文件将包含大量空字节。这些空字节将搞砸通过 fgets()
读取的数据的处理。您将错过空字节和它们之后的任何其他字节。 fgets()
不会告诉您它读取了多少字节,因此您无法安全地读取空字节。
您很可能需要使用 fread()
和 fwrite()
。至少,那些不会被数据中嵌入的空值混淆。
我编译了以下代码 运行:
$ ./run_curl 'http://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz'
.
但是我无法获取要下载的文件的完整字节。为什么?
我使用 curl --silent 'http://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz' > a.tgz
会得到完整的字节。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 512
void download_pkg(const char* url)
{
char content[SIZE] = {0};
FILE *fp = NULL;
char cmd[255] = {0};
FILE *fp_download = fopen("a.tgz", "w");
sprintf(cmd, "curl --silent '%s'", url);
fp = popen(cmd, "r");
while(fgets(content, SIZE - 1, fp) != NULL) {
fputs(content, fp_download);
}
fclose(fp_download);
pclose(fp);
return;
}
int main(int argc, char *argv[])
{
download_pkg(argv[1]);
return 0;
}
编辑:
根据 Jonathan Leffler 的
int size_read = 0;
while((size_read = fread(content, sizeof(char), SIZE - 1, fp)) > 0) {
fwrite(content, sizeof(char), size_read, fp_download);
}
gzipped tar 文件将包含大量空字节。这些空字节将搞砸通过 fgets()
读取的数据的处理。您将错过空字节和它们之后的任何其他字节。 fgets()
不会告诉您它读取了多少字节,因此您无法安全地读取空字节。
您很可能需要使用 fread()
和 fwrite()
。至少,那些不会被数据中嵌入的空值混淆。