0

我在使用 fseek 时遇到问题。我有一个包含获取的 HTTP 数据的文件指针。然后我让 libmagic 确定文件的 mime 类型,然后想倒带:

char *mime_type (int fd)
{
    char *mime;
    magic_t magic;

    magic = magic_open(MAGIC_MIME_TYPE);
    magic_load(magic, MAGIC_FILE_NAME);
    mime = (char*)magic_descriptor(magic, fd);

    magic_close(magic);
    return (mime);
}

int fetch_pull() {
    fetch_state = fopen("/tmp/curl_0", "r");
    if (fetch_state == NULL) {
      perror("fetch_pull(): Could not open file handle");
      return (1);
    }
    fd = fileno(fetch_state);
    mime = mime_type(fd);
    if (fseek(fetch_state, 0L, SEEK_SET) != 0) {
      perror("fetch_pull(): Could not rewind file handle");
      return (1);
    }
    if (mime != NULL && strstr(mime, "text/") != NULL) {
      /* do things */
    } else if (mime != NULL && strstr(mime, "image/") != NULL) {
      /* do other things */
    }
    return (0);
}

这会抛出“fetch_pull():无法倒带文件句柄:错误的文件描述符”。怎么了?

4

1 回答 1

2

/tmp/curl_0是一个管道,不是吗?您不能倒带管道。读的东西没了。

而且您不能将 FILE 操作和文件描述符操作结合起来,因为 FILE 有一个额外的缓冲区,它们会提前读取。

如果/tmp/curl_0常规文件,则使用 . 打开文件描述符open(const char *path, int oflag, ...)。调用后mime_type(fd),您可以先倒带流,然后将文件描述符包装到 FILE 句柄中fdopen(int fildes, const char *mode)。或者只是关闭文件描述符,然后使用常规fopen()

int fd = open("/tmp/curl_0", O_RDONLY);
if (fd == -1) {
    perror("Could not open file");
    return -1;
}
char *mime = mime_type(fd);

    /***** EITHER: */

close(fd);
FILE *file = fopen("/tmp/curl_0", "r");

    /***** OR (the worse option!) */

if (lseek(fd, 0, SEEK_SET) == -1) {
    perror("Could not seek");
    return -1;
}
FILE *fdopen = fopen(fd, "r");

    /***********/

if (!file) {
    perror("Could not open file");
    return -1;
}
/* do things */
fclose(file);
于 2014-09-24T16:44:44.497 回答