我正在寻找与FILE * join (FILE * a, FILE * b)
等效的函数popen("cat a b", "r");
。也就是说,调用join
应该会产生一个新的文件指针,该指针包含所有文件a
,然后包含所有文件b
。
最好join
应该是惰性的,以便在文件b
的所有文件都用完之前不读取文件a
。
答案 0 :(得分:3)
您不能为此创建可移植函数。可以在Linux / Glibc上使用fopencookie
或在BSD上使用funopen
。请参阅:Is it possible to use functions that acts on FILE* on custom structures?尽管我不知道Windows上有任何方法。
您只需要提供一种读取方法即可尝试从第一个文件句柄中读取给定的字节数,而该文件句柄到目前为止还没有文件结束条件。
答案 1 :(得分:2)
我不认为您可以:至少在不创建临时文件并将结果包装在FILE*
中的情况下,该结果使您可以使用fread()
等“常规”文件访问功能。
逻辑很简单:从a
读取到文件结束,然后从b
读取,但是您不能“进入” {{1} }处理例程(根据Antti's answer,至少要以一种可移植的方式进行处理),以使例程能够从一个文件切换到另一个文件。
您可以编写一个函数来替换使用两个FILE*
自变量的特定文件处理函数,例如您可以定义FILE*
接受两个流,并从其中一个读取直到耗尽为止,然后切换到另一个。
或者您可以创建自己的fread2(void *ptr, size_t size, size_t nmemb, FILE *stream1, FILE* stream2)
结构(由FILEPAIR
返回/填充),该结构保存对两个join()
的引用,然后创建在该结构(例如FILE*
。
答案 2 :(得分:0)
这是我的加入函数,有关兼容性问题,请参见Antti Haapala's answer。
typedef struct {
FILE * a;
FILE * b;
} myCookie;
ssize_t join_read(myCookie * cookie, char *buf, size_t size) {
size_t s = fread(buf, 1, size, cookie->a);
if (s < size)
s += fread(buf+s, 1, size-s, cookie->b);
return s;
}
int join_close(myCookie * cookie) {
return fclose(cookie->a) | fclose(cookie->b);
}
FILE * join (FILE * a, FILE * b) {
myCookie * cookie = malloc(sizeof(myCookie));
cookie->a = a;
cookie->b = b;
return fopencookie(cookie, "r", (cookie_io_functions_t)
{ join_read
, NULL
, NULL
, join_close });
}
由于这已经是Linux专用的,所以我们也可以定义一个函数:
FILE * empty () {
return fopen("/dev/null", "r");
}
现在文件指针在join
和empty
下形成一个monoid!
答案 3 :(得分:-1)
没有否这样的功能。您需要用它来编写自己的内容。