преобразовать char* в FILE* без сохранения файла

я пытаюсь открыть существующий файл в режиме «rb», и мне нужно расшифровать, возвращая новый ФАЙЛ * без перезаписи исходного файла или создания нового временного. Короче говоря, мне нужно что-то вроде этого:

FILE *decrypt(){
    FILE *cryptedfile = fopen("file.ext", "rb");

    //... my decrypter code

    return (the decrypted file as FILE*).
}

Итак, есть ли способ сделать что-то вроде «перевести char* в FILE*»?

я безуспешно пробовал много разных решений, я также пытался создать новый tmpfile(), но результат, похоже, не работает должным образом, и я все равно не хочу создавать tmpfile, а просто храню его в памяти.

спасибо :)


person Giuseppe    schedule 24.10.2018    source источник
comment
Единственный способ получить действительный FILE * — это использовать fopen. Почему бы вам просто не вернуть расшифрованное содержимое в массиве байтов?   -  person Fiddling Bits    schedule 24.10.2018
comment
Вы уже преобразовали свой const char* в FILE*, когда позвонили fopen.   -  person François Andrieux    schedule 24.10.2018
comment
конечно, мой код расшифровщика обработает содержимое файла и вернет его как char*, но мне нужно снова преобразовать его в FILE* без сохранения.   -  person Giuseppe    schedule 24.10.2018
comment
return (the decrypted file as FILE*). то надо создать новый расшифрованный файл и записать в него закрыть его, потом снова открыть для чтения. Кажется странным требованием или, по крайней мере, небезопасным.   -  person drescherjm    schedule 24.10.2018
comment
Почему? Какой цели служит наличие FILE *? Что плохого в том, что char * указывает на расшифрованные данные?   -  person dbush    schedule 24.10.2018
comment
мне нужен FILE*, а не char*, потому что я использую сторонний код, который требует FILE* для выполнения других процессов. :(   -  person Giuseppe    schedule 24.10.2018
comment
я не хочу создавать новый временный файл, так как зашифрованные данные очень важны :\   -  person Giuseppe    schedule 24.10.2018
comment
Если вы работаете в системе, совместимой с POSIX, вы можете использовать fmemopen().   -  person    schedule 24.10.2018
comment
Кроссплатформенность: github.com/Snaipe/fmem   -  person    schedule 24.10.2018
comment
Тот же вопрос: stackoverflow.com/q/24683052/3002139   -  person Baum mit Augen    schedule 24.10.2018
comment
Возможные дубликаты: stackoverflow.com/q/5135854/3002139 stackoverflow.com/q/539537/3002139   -  person Baum mit Augen    schedule 24.10.2018


Ответы (1)


После расшифровки данных вы можете создать канал для передачи расшифрованных данных, а затем вы можете вернуть конец канала для чтения для чтения данных.

FILE *decrypt(){
    FILE *cryptedfile = fopen("file.ext", "rb");

    char *data;
    int len;
    // load decrypted data into "data" and length info "len"

    int p[2];
    if (pipe(p) == -1) {
        perror("pipe failed");
        return NULL;
    }

    int rval;
    if ((rval = write(p[1], data, len)) == -1) {
        perror("write failed");
        close(p[0]);
        close(p[1]);
        return NULL;
    } else if (rval < len) {
        printf("write failed, wrote %d, expected %d\n", rval, len);
        close(p[0]);
        close(p[1]);
        return NULL;
    }

    return fdopen(p[0], "r");
}

В качестве альтернативы вы также можете использовать fmemopen:

FILE *decrypt(){
    FILE *cryptedfile = fopen("file.ext", "rb");

    char *data;
    int len;
    // load decrypted data into "data" and length info "len"

    return fmemopen(data, len, "rb");
}
person dbush    schedule 24.10.2018
comment
Что произойдет, если расшифрованные данные превысят размер буфера канала? - person Shawn; 24.10.2018
comment
@Shawn Вы получите ошибку записи, если это произойдет. В Linux по умолчанию установлено значение 64 КБ, но его можно увеличить с помощью fcntl с помощью параметра F_SETPIPE_SZ. - person dbush; 24.10.2018
comment
Спасибо всем за эти ответы за такое короткое время @dbush Я попробовал ваш код, и он работает, но, похоже, он работает, только если char * не содержит пробелов. если данные содержат пробел, программа продолжает работать, ничего не делая. - person Giuseppe; 24.10.2018
comment
@ Джузеппе рад, что смог помочь. Не стесняйтесь [принять этот ответ[(stackoverflow.com/help/accepted-answer), если вы нашли его полезным. - person dbush; 25.10.2018
comment
извините, не пробелы, а возвращает символ типа \n - person Giuseppe; 25.10.2018
comment
Я объясню, например: если я устанавливаю data = helloworld и len = 10, он работает отлично. но если data = hello world и len = 11, программа останется в живых, ничего не делая; но если len = 5 (до приветствия), он работает, записывая только приветственное слово. что случилось? - person Giuseppe; 25.10.2018
comment
я исправил, заменив pipe(p) на _pipe(p, len, O_BINARY) - person Giuseppe; 25.10.2018