Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is there a way to create a file stream from a C stream (a FILE *) ?

6 views
Skip to first unread message

Timothy Madden

unread,
Aug 28, 2010, 5:58:12 PM8/28/10
to
Hello

The C language has a function tmpfile() that just opens a temporary file
for reading and writing that has the property that is automatically
removed when closed.

However I would like to use such a file as a C++ standard file stream,
to use char iterators to read and write the content (I want to write a
zip file and then encode it as multipart/form-data to send the archive
to a web server, and I need to check that the archive does not
accidentally include the chosen multipart boundary marker).

Is there a way to construct a standard C++ file stream from a C file
stream pointer ? That is, can I construct a std::stream from a FILE * ?
Is there a C++ specific function that creates such a temporary file,
deleted automatically ?

Thank you,
Timothy Madden

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Daniel Krügler

unread,
Aug 28, 2010, 10:38:18 PM8/28/10
to
On 28 Aug., 23:58, Timothy Madden <terminato...@gmail.com> wrote:
> Hello
>
> The C language has a function tmpfile() that just opens a temporary file
> for reading and writing that has the property that is automatically
> removed when closed.
>
> However I would like to use such a file as a C++ standard file stream,
> to use char iterators to read and write the content (I want to write a
> zip file and then encode it as multipart/form-data to send the archive
> to a web server, and I need to check that the archive does not
> accidentally include the chosen multipart boundary marker).
>
> Is there a way to construct a standard C++ file stream from a C file
> stream pointer ? That is, can I construct a std::stream from a FILE * ?

There is no standard means to realize that, but
AFAIK some vendors provide it as extension. There
had been several discussions whether this should
be a required functionality, but if my remembrance
is not too wrong, such guarantee cannot be given for
all implementations, therefore chances are low for
standardizing this.

> Is there a C++ specific function that creates such a temporary file,
> deleted automatically ?

There is none. I agree that such a functionality
would be quite useful for C++ file streams.
For the next TR of C++ it is quite probable, that
a filesystem library could be added (based on boost
filesystem), but IMO this specific functionality
does not exist in boost (boost::unique_path mimics
tmpnam, but not tmpfile).

HTH & Greetings from Bremen,

Daniel Krügler

Timothy Madden

unread,
Aug 29, 2010, 11:46:05 AM8/29/10
to


I am sad to hear that functionality from C is now no longer available in C++. Ok not really unavailable, but rather far away ... :)

Why would an implementation not guarantee that an istream-derived class can wrap a legacy FILE * ? It seems doable even with a user-written class, I would like to see those discussions you said ...

Anyway I guess I will have to use the POSIX function fileno() (which is pretty much ok since POSIX functions are also standard and portable), and then use boost::iostreams library to create a stream from the returned POSIX open file descriptor.

Thank you,
Timothy Madden

nm...@cam.ac.uk

unread,
Aug 29, 2010, 11:45:29 AM8/29/10
to
In article <c73627ae-f651-4c8a...@a36g2000yqc.googlegroups.com>,

=?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel....@googlemail.com> wrote:
> On 28 Aug., 23:58, Timothy Madden <terminato...@gmail.com> wrote:
>>
>> Is there a way to construct a standard C++ file stream from a C file
>> stream pointer ? That is, can I construct a std::stream from a FILE * ?
>
> There is no standard means to realize that, but
> AFAIK some vendors provide it as extension. There
> had been several discussions whether this should
> be a required functionality, but if my remembrance
> is not too wrong, such guarantee cannot be given for
> all implementations, therefore chances are low for
> standardizing this.

Eh? That's nonsense - I am not denying that someone told you
that, but it demonstrably ain't so. There is ample slop in the
specification of both to allow for minor semantic constraints,
and that is the most that would be needed. Exactly the same applies
to creating a C FILE object from a POSIX descriptor, which is done
all the time.

Exactly as with that, using both the C++ file stream and C <stdio.h>
facilities on the same file would be implementation-dependent, but
that applies to most of the I/O morass, whether in C++, C or POSIX.
Given the wild differences between operating systems' I/O models,
it isn't possible to design a language I/O interface that is both
very flexible and truly portable.

If all else fails, all that has to be done is that the C++ stream
is implemented using the C FILE as a device interface, and that's
old and well-understood technology. It wouldn't be hard to write
just such a reference implementation, but it might well involve
replicating most of the C++ streams code, which is tedious. Or it
might not - I don't know C++ well enough to be sure.

What the statement almost certainly meant was that the implementor
didn't want to do it, because it would require restructuring all of
his I/O code, and so said that it wasn't possible. If that's the
case for enough implementors (or critical ones), then the chances
of standardising it are indeed low. But that's NOT because it is
impossible.


Regards,
Nick Maclaren.

Daniel Krügler

unread,
Aug 30, 2010, 12:33:18 AM8/30/10
to
On 29 Aug., 17:45, n...@cam.ac.uk wrote:
> In article <c73627ae-f651-4c8a-91db-c7cee1cf8...@a36g2000yqc.googlegroups.com>,

>
> =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.krueg...@googlemail.com> wrote:
> > On 28 Aug., 23:58, Timothy Madden <terminato...@gmail.com> wrote:
>
> >> Is there a way to construct a standard C++ file stream from a C file
> >> stream pointer ? That is, can I construct a std::stream from a FILE * ?
>
> > There is no standard means to realize that, but
> > AFAIK some vendors provide it as extension. There
> > had been several discussions whether this should
> > be a required functionality, but if my remembrance
> > is not too wrong, such guarantee cannot be given for
> > all implementations, therefore chances are low for
> > standardizing this.
>
> Eh? That's nonsense - I am not denying that someone told you
> that, but it demonstrably ain't so. There is ample slop in the
> specification of both to allow for minor semantic constraints,
> and that is the most that would be needed. Exactly the same applies
> to creating a C FILE object from a POSIX descriptor, which is done
> all the time.

I'm happy to hear that there might be a good chance
to realize that.

> What the statement almost certainly meant was that the implementor
> didn't want to do it, because it would require restructuring all of
> his I/O code, and so said that it wasn't possible.

This description concerns me: Surely is a valid argument, isn't it?
If this binding should be easily provided by just inspecting the
FILE object's internal representation, why should there be any
restructuring needed?

Greetings from Bremen,

Daniel Krügler


Chris Vine

unread,
Aug 30, 2010, 10:36:47 AM8/30/10
to
On Sat, 28 Aug 2010 15:58:12 CST

> Is there a way to construct a standard C++ file stream from a C file
> stream pointer ? That is, can I construct a std::stream from a FILE
> * ? Is there a C++ specific function that creates such a temporary
> file, deleted automatically ?

Yes, you can write your own streambuffer classes. Here are some classes
which use stdio C streams to read and write to unix file
descriptors with fdopen(), which you can easily tweak to accept the
FILE* in the first place and bypass fdopen().

http://www.cvine.freeserve.co.uk/fdstream/c_streams/fdstream.h
http://www.cvine.freeserve.co.uk/fdstream/c_streams/fdstream.cc

Note that this is not the best way of writing a streambuffer class for
unix file descriptors: for file descriptors, you can and should provide
your own buffers rather than interfacing with the stdio ones, and these
classes are really more of an exercise. However, it is the way to
write a streambuffer class for FILE*.

Chris

nm...@cam.ac.uk

unread,
Aug 30, 2010, 10:35:07 AM8/30/10
to
In article <9df7401d-dcaa-4541...@i31g2000yqm.googlegroups.com>,
=?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel....@googlemail.com> wrote:
>
> [ Creating a C++ stream object from a C FILE object. >

>
> I'm happy to hear that there might be a good chance
> to realize that.

Technically, yes. The politics are something else. The best
solution would be the BCPL one of allowing an abstract stream
interface at the other end. The killer is that the politically
obvious design to use is POSIX, and that's a technical mess and
VERY system-dependent. There are worse ones, of course, such as
zOS BSAM - which nowadays is the operating system equivalent of
Ultima Thule.

>> What the statement almost certainly meant was that the implementor
>> didn't want to do it, because it would require restructuring all of
>> his I/O code, and so said that it wasn't possible.
>
> This description concerns me: Surely is a valid argument, isn't it?
> If this binding should be easily provided by just inspecting the
> FILE object's internal representation, why should there be any
> restructuring needed?

Lets's say that the C and C++ libraries are implemented mostly by
calls to an underlying interface (say, POSIX, but it might well be
the implementor's own). The restructuring would be to either
implement a reverse interface from that to C FILEs, or to make the
C++ use the C FILE.

Yes, they could also implement duplicate code, which would need no
restructuring, but it would be a long-term maintenance problem.


Regards,
Nick Maclaren.

Jeff Flinn

unread,
Aug 30, 2010, 7:56:46 PM8/30/10
to
Timothy Madden wrote:
> Hello
>
> The C language has a function tmpfile() that just opens a temporary file
> for reading and writing that has the property that is automatically
> removed when closed.
>
> However I would like to use such a file as a C++ standard file stream,
> to use char iterators to read and write the content (I want to write a
> zip file and then encode it as multipart/form-data to send the archive
> to a web server, and I need to check that the archive does not
> accidentally include the chosen multipart boundary marker).
>
> Is there a way to construct a standard C++ file stream from a C file
> stream pointer ? That is, can I construct a std::stream from a FILE * ?
> Is there a C++ specific function that creates such a temporary file,
> deleted automatically ?

The boost.iostreams library makes it trivial to wrap a FILE* with a
source/sink allowing it to be read/written to via std streams interface.
If you can get a file descriptor or a Win32 HANDLE from the FILE* there
already is boost::iostreams::file_descriptor classes provided.

Jeff

0 new messages