1

Is there anything like a string file in stdio/string/stdlib ? I mean a special way to fopen a FILE stream, which actually directs the writes to an internal buffer and takes care of buffer allocation/reallocation ? After fclose, the text should be available as null-terminated char[] or similar.

I need to interface to legacy code that receives a FILE* as an argument and writes to it, and I'd prefer to avoid writing to a temporary disk file.

Other forms of storage could do instead of char[] (f.i. string), but a FILE* pointer must be available.

I am looking for an alternative to creating a temporary disk file.

nwellnhof
  • 32,319
  • 7
  • 89
  • 113
  • Shouldn't this question be tagged as C? – Axalo Feb 18 '15 at 17:47
  • Actually it will be called from C++ CLI. –  Feb 18 '15 at 17:48
  • Why not use the STL? – Axalo Feb 18 '15 at 17:50
  • 1
    How will STL support a Posix FILE ? –  Feb 18 '15 at 17:51
  • Maybe I'm not understanding what you mean, but why not use a char * and realloc when necessary? – Disco Globeulon Feb 18 '15 at 17:53
  • 2
    On Linux you can use `fopencookie` or `open_memstream` to do this. I don't think Windows has an equivalent. – interjay Feb 18 '15 at 17:55
  • @Josh: Because the legacy code will not tell me when a realloc is required. That should be handled by the string FILE, which receives the write requests. –  Feb 18 '15 at 17:55
  • No, there isn't anything like STL in C. You'll need to write your own buffer struct and reallocate space, as needed. – Alex Reynolds Feb 18 '15 at 17:55
  • 2
    You can get a std::fstream from a FILE * [on windows](http://stackoverflow.com/questions/2746168/how-to-construct-a-c-fstream-from-a-posix-file-descriptor). – Axalo Feb 18 '15 at 17:57
  • Why is this tagged posix when you said you use C++/CLI? Which OS and compiler are you using? – interjay Feb 18 '15 at 18:01
  • @interjay: it seems that open_memstream is exactly what I need (there's also a fmemopen but it doesn't grow the buffer). fopencookie could do as well as it allows you to write your own hooks. I would need a Windows equivalent of one of these. –  Feb 18 '15 at 18:01
  • @interjay: the calling code is written in C++ CLI with MSVC, and invokes a native API that uses Posix. –  Feb 18 '15 at 18:02
  • If you aren't actually on a POSIX system then I suggest removing that tag. – interjay Feb 18 '15 at 18:06
  • 1
    @interjay: The POSIX tag is there to stress C POSIX library compliance (stdio). –  Feb 18 '15 at 18:07
  • If this is for Window only, I'd tag the question [windows]. – alk Feb 18 '15 at 18:23
  • 1
    @YvesDaoust stdio is part of the C standard. POSIX is a standard which includes that but also a lot more (for example, it defines `open_memstream`, which isn't in the C standard) and isn't directly supported on Windows. – interjay Feb 18 '15 at 18:30
  • Note that `fmemopen()` and `open_memstream()` are not in POSIX.1-2001, but only in POSIX.1-2008. There are still a good number of systems that comply with the former but not the latter, and on such systems you are unlikely to find those functions available. I'm not sure whether Windows is among them. – John Bollinger Feb 18 '15 at 18:32
  • 1
    If you want a solution that is based only on the C standard library (for maximum portability, including to Windows) then you are out of luck. The standard library does not provide a `FILE` view of memory, nor any mechanism by which you could portably roll your own. – John Bollinger Feb 18 '15 at 18:35
  • @JohnBollinger: I just need a solution that supports the FILE type and runs under Windows. I don't care about portability. –  Feb 18 '15 at 18:42

2 Answers2

0

fmemopen & open_memstream are in the POSIX 2008 standard, probably inspired by GNU libc string streams, and give in-memory FILE* streams.

See also this question quite similar to yours, and also that answer.

BTW, many operating systems have RAM based or virtual memory based filesystems (à la tmpfs)

If you are coding in C++11 (not in C) and perhaps for some earlier C++ standard you can of course use std::stringstream-s

So you could use open_memstream on Posix, and some other solution on Windows (just with #if _POSIX_C_SOURCE > 200809L per feature_test_macros(7) ...)

The C standard does not provide (yet) any in-memory FILE streams, so if you need them you have to code or use platform-specific functions.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

Create the temporary file using CreateFile(... FILE_ATTRIBUTE_TEMPORARY, FILE_FLAG_DELETE_ON_CLOSE ...) and then convert the HANDLE to FILE*.

You said you didn't like a write to a temporary file, so these flags to CreateFile are a strong hint to Windows to keep the file in cache if possible. And if Windows would run of of RAM, even a char[] can end up in a swap file anyway.

Community
  • 1
  • 1
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Yep, that's my current solution. I don't mind that there can indeed be disk accesses, I am more worried by the need to access the file system and be allowed to do so. –  Feb 19 '15 at 09:52
  • @YvesDaoust: Why would that be a problem? `GetTempPath` should give you a writeable directory. Create a GUID for a filename and you don't have collisions. But if you do have a " current solution" you really should include that in the question! – MSalters Feb 19 '15 at 09:58