2017-09-29 7 views
1

C++ std::istream 입력 메모리 스트림이 주어지면 먼저 데이터를 디스크에 쓰지 않고 C 스트림 (FILE*)에 해당 스트림의 데이터를 직접 쓸 수 있습니까?C 파일 스트림에 대한 C++ 메모리 스트림

내가 묻는 이유는 FILE*을 취하는 C 인터페이스를 가지고 있기 때문에 압축되거나 압축되지 않은 입력 파일을 투명하게 지원하기 위해서입니다.

입력 파일을 취하는 래퍼 함수를 ​​작성한 다음 boost::iostreams을 사용하여 필요한 경우 압축 해제를 수행하는 필터링 스트림을 만든 다음 압축 해제 된 데이터를 어떻게 든 C API로 전달합니다.

간단한 방법은 압축 파일의 압축을 풀고 압축 해제 된 데이터를 디스크에 쓴 다음 fopen 임시 파일을 작성하는 것입니다. 임시 파일을 만들지 않아도되고 싶습니다.

다른 옵션은 메모리의 모든 데이터를 압축 해제 한 다음 fmemopen을 사용하여 압축 해제 된 데이터에 FILE*을 얻는 것입니다. 즉, 많은 데이터를 할당해야 할 수도 있지만 버퍼링 된 솔루션을보고 싶습니다. 어떤 방법으로 가능합니까? 당신이 GNU 시스템의 경우

+0

'open_memstream'을보세요. 원하는대로 할 수 있습니다. –

+0

스트리밍/버퍼 된 데이터를 원한다면'pipe'와'fdopen'이'fmemopen'보다 낫습니다. – Sneftel

+0

[boost :: zlib] (http://www.boost.org/doc/libs/release/libs/iostreams/doc/classes/zlib.html)가 도움이됩니까? – jxh

답변

4

, (리눅스, Glibc의), 당신은 당신의 디코딩 작업에 대한 FILE * 래퍼를 만들 fopencookie를 사용할 수 있습니다

FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs); 

[...]

fopencookie() 함수는 fopen (3)과 비슷한 용도로 사용됩니다. 은 새 스트림을 열고 해당 스트림에서 작동하는 데 사용되는 인 FILE 개체에 대한 포인터를 반환합니다.

쿠키 인수는 새 스트림과 연결될 호출자의 쿠키 구조 에 대한 포인터입니다. 이 포인터는 표준 I/O 라이브러리가 을 호출 할 때 첫 번째 인수로 제공되는 입니다.

mode 인수는 fopen (3)과 같은 용도로 사용됩니다. 다음 모드가 지원됩니다 (r, w, a, r +, w + 및 a +). 자세한 내용은 fopen (3) 을 참조하십시오.

io_funcs 인수는이 스트림을 구현하는 에 사용되는 프로그래머 정의 후크 함수를 가리키는 네 개의 필드 을 포함하는 구조입니다.

(I 내 대답에 전체 맨 페이지를 복사하지 않았다)

typedef struct { 
    cookie_read_function_t *read; 
    cookie_write_function_t *write; 
    cookie_seek_function_t *seek; 
    cookie_close_function_t *close; 
} cookie_io_functions_t; 

을 [...] 다음과 같이 구조가 정의된다.

은 기본적으로 다음을 수행 할 수 있습니다 : 그것은 정확히 같은 일을 달성하기 위해 약간 다른 API 단지 인 funopen 함께 제공하기 때문에 BSD에

ssize_t my_read(void *cookie, char *buf, size_t size) { 
    std::istream *the_stream = static_cast<std::istream*>(cookie); 
    // insert magic 
    return bytes_read; 
} 

cookie_io_functions_t my_functions = { 
    my_read, 
    NULL, 
    NULL, 
    NULL, 
}; 

... 

FILE *wrapped = fopencookie(static_cast<void *>&stream, "rb", my_functions); 

은/OSX, 당신은, 동등하게 운이 좋은 것입니다.

그리고 Windows를 지원하고 싶다면, poor you.

+0

미안하지만,이 문제에 대해서는 언급하지 않았지만, 운좋게도 저는 리눅스에 있습니다. –