Click here to Skip to main content
15,867,777 members
Articles / Desktop Programming / MFC
Article

A Handy Guide To Handling Handles

Rate me:
Please Sign up or sign in to vote.
4.73/5 (24 votes)
24 Oct 20015 min read 287.1K   59   38
The secrets of File Handles and their relationship to File *, CFile, CStdioFile, etc.

Disclaimer

I'm working on this essay. However, the information that is already here is sufficiently useful that I decided to post in, in spite of the fact that I've only covered a small part of handles. Over the next few months, I'll be enhancing it. So be patient; more is coming.

File Handles

I have a FILE *. Or I have a CFile or CStdioFile. What is its handle? And what handle is it?

There are several representations of handles for files at the application level. There are the file handles delivered by the C library, there are FILE * objects, and there are operating system file handles. They are all interchangeable, but only if you know what you are doing. 

They are not necessarily interchangeable on an instant's notice, because of issues such as buffering. Thus if you reach into a FILE * and grab the underlying operating system handle and do a WriteFile, you will probably end up with a seriously corrupted file because there is buffered data being managed by the FILE * object. Therefore, unless you understand what needs to be done to flush buffers and maintain consistency in the various file handle images of the file contents and position, you are going to end up in serious trouble.

More typically, you have a fresh, newly-opened handle of one type and wish to now associate it with a representation more suitable for your task. For example, the C library function fopen does a pitiful job of handling file sharing, a concept which was nonexistent on the Unix operating system in which it was first specified. You want to use the full Win32 file sharing, but don't want to have to do raw WriteFile operations. And maybe you can't because you are retrofitting something into an existing, possibly portable-across-operating-systems source set, and you're writing the OS-specific module. So you can get a genuine Win32 HANDLE from CreateFile, and you want to associate it with a FILE * so you can now use it conveniently. Or even associate it with a C++ fstream. Keep reading!

C library "handles" are small integers that index into a table in the C runtime library. The C library has traditionally limited the number of simultaneously open files to some very restrictive number of handles, such as 16. This is no longer true in Win32. The C library in Win32 now supports up to 2048 low-level handles. The default is to allow a maximum of 512 FILE * objects, although you can easily change this limit up to the maximum of 2048 by calling _setmaxstdio.

If you don't see the transformation you need in the table below, you will need to use a combination of the transformations. For example, to transform a HANDLE to an fstream, you need to do something like

HANDLE h = ::CreateFile(...);
fstream f;
f.attach(_open_osfhandle(h));

Summary of Direct File Handle Transformations

FromSourceTouse
HANDLEWin32

CreateFile

C Library handle_open_osfhandle
<A href="#HANDLE to CFile">CFile</A>CFile::CFile
C Library handle<io.h>

_open
_sopen

<A href="#C Library handle to Win32 Handle">HANDLE</A>_get_osfhandle
<A href="#C Library handle to FILE *">FILE *</A>_fdopen
<A href="#HANDLE to fstream">fstream</A>fstream::fstream or<BR>fstream::attach
FILE *<stdio.h>

fopen

C Library handle_fileno
<A href="#FILE * to CStdioFile">CStdioFile</A>CStdioFile::CStdioFile
CFileMFC<A href="#CFile to HANDLE">HANDLE</A>m_hFile data member
CStdioFileMFC<A href="#CStdioFile to FILE *">FILE *</A>m_pStream data member
stdxxxWin32<A href="#stdxxx to HANDLE">HANDLE</A>GetStdHandle
fstreamC++ LibraryC Library handle.fd method of fstream

Image 1


Win32 HANDLE to C Library handle

<io.h>
int _open_osfhandle(long oshandle, int flags)

This takes a HANDLE value and returns a small integer that can be used to interface with the C library. The flags value includes O_APPEND, O_RDONLY, and O_TEXT. Note that this prototype assumes that a long and a HANDLE are the same size, and you will have to do a cast to get it past the compiler, for example

int h = _open_osfhandle((long) myhandle, 0);

It is not clear at this point to me what Microsoft will do in Win64 for this library call, because handles in Win64 (I think) will be 64 bits wide.

back to index


C Library handle to FILE *

Given a C library file handle, you can convert it to a FILE* by calling the function _fdopen, passing in the C library file handle and getting in return a FILE *.

<stdio.h><code>
</CODE>int _fdopen(int filehandle, const char * mode)

where mode  is any of the mode values you can provide to fopen, such as "r", "rw", "w", etc.

back to index


FILE * to C Library handle

Give a FILE * object, you can obtain the underlying C library handle by using _fileno

<stdio.h>
<code>int _fileno(FILE * f)</CODE>

back to index


C Library handle to Win32 Handle

<io.h>
long _get_osfhandle(int filehandle)

This takes a C library file handle and returns the underlying Win32 HANDLE.

back to index


CFile to HANDLE

Underlying a CFile object is a system file handle. Sometimes. Maybe. In a raw CFile, the m_hfile member is a system file handle. However, Microsoft cautions that this may change in a derived class. 

back to index


HANDLE to CFile

To associate a CFile object with an operating system file handle, you use the CFile constructor of the form

CFile::CFile(HANDLE h)

Whether you do this in a stack variable or use heap allocation depends on the nature of your application.

CFile file(myhandle);

or

CFile * file = new CFile(myhandle);

back to index


CStdioFile to FILE *

The m_pStream member of CStdioFile is the reference to the FILE * object that underlies it.

back to index


FILE * to CStdioFile

To associate a CStdioFile object with an operating system file handle, you use the CStdioFile constructor of the form

CStdioFile::CStdioFile(FILE * f)

Whether you do this in a stack variable or use heap allocation depends on the nature of your application.

<code>CStdioFile file(myfile);</CODE>

or

CStdioFile * file = new CStdioFile(myfile);

back to index


stdxxx to HANDLE

If you need a handle to stdin, stdout, or stderr, without using the stdio.h library, you can use the API call GetStdHandle, specifying one of the constants, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE. These return a HANDLE  value which can be used for ReadFile, WriteFile, or with any of the above.

back to index


C Library handle to fstream

If you have a C Library handle (the small integer from _open or _sopen) and need a C++ fstream-class object, take a look at the fstream constructor. One form takes a C file descriptor:

fstream(filedesc fd)

You can also use the fstream::attach method to attach a file descriptor to an existing fstream:

fstream f; 
f.attach(fd);

For this to work, there must not be a file descriptor already attached to the fstream.

back to index


<A name="fstream to C Library handle">fstream to C Library handle</A>

To obtain the underlying C library handle from an fstream, use the .fd method 

fstream f;
f.attach(fd)
ASSERT(fd == f.fd()) 

back to index

Inheritable handles

OK, someday soon...

Other Handles

Likewise...

Send mail to newcomer@flounder.com with questions or comments about this article.
Copyright © 1999 [] All Rights Reserved
www.flounder.com/mvp_tips.htm

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Retired
United States United States
PhD, Computer Science, Carnegie Mellon University, 1975
Certificate in Forensic Science and the Law, Duquesne University, 2008

Co-Author, [i]Win32 Programming[/i]

Comments and Discussions

 
GeneralMy vote of 4 Pin
Adi Shavit14-Jun-11 21:11
Adi Shavit14-Jun-11 21:11 
GeneralMy vote of 4 Pin
Gokulnath00710-May-11 1:15
Gokulnath00710-May-11 1:15 
QuestionHow to read no of row.. Pin
Shah Satish2-Dec-06 11:13
Shah Satish2-Dec-06 11:13 
AnswerRe: How to read no of row.. Pin
Joseph M. Newcomer2-Dec-06 12:09
Joseph M. Newcomer2-Dec-06 12:09 
GeneralI have a same problem! Pin
dSolariuM17-Oct-06 21:35
dSolariuM17-Oct-06 21:35 
Hi,
I have problem with ddk.
When I include ntddk.h or other DDK headers I get hundreds of errors.
What Should I do?
please help me.

Every new thing you learn,Gives you a new personality.

GeneralRe: I have a same problem! Pin
Joseph M. Newcomer18-Oct-06 4:21
Joseph M. Newcomer18-Oct-06 4:21 
GeneralRe: I have a same problem! Pin
dSolariuM19-Oct-06 8:24
dSolariuM19-Oct-06 8:24 
GeneralRe: I have a same problem! Pin
Joseph M. Newcomer19-Oct-06 8:57
Joseph M. Newcomer19-Oct-06 8:57 
GeneralIStream to FILE * Pin
Fwzklmn7-Jun-06 14:23
Fwzklmn7-Jun-06 14:23 
Generalno fstream::attach any more Pin
Artem Alimarine23-Feb-06 5:36
Artem Alimarine23-Feb-06 5:36 
QuestionConvert fd to handle? Pin
SteQve26-Oct-05 9:10
SteQve26-Oct-05 9:10 
AnswerRe: Convert fd to handle? Pin
Joseph M. Newcomer26-Oct-05 16:10
Joseph M. Newcomer26-Oct-05 16:10 
GeneralRe: Convert fd to handle? Pin
SteQve27-Oct-05 5:47
SteQve27-Oct-05 5:47 
GeneralRe: Convert fd to handle? Pin
Joseph M. Newcomer27-Oct-05 14:16
Joseph M. Newcomer27-Oct-05 14:16 
GeneralBe careful with _get_osfhandle under Windows Pin
Stitchyphish24-Aug-04 11:26
Stitchyphish24-Aug-04 11:26 
GeneralRe: Be careful with _get_osfhandle under Windows Pin
Joseph M. Newcomer24-Aug-04 19:09
Joseph M. Newcomer24-Aug-04 19:09 
QuestionGet a "Fake" Handle? Pin
C. Augusto Proiete4-Aug-03 5:51
C. Augusto Proiete4-Aug-03 5:51 
AnswerRe: Get a &quot;Fake&quot; Handle? Pin
John M. Drescher4-Aug-03 6:54
John M. Drescher4-Aug-03 6:54 
GeneralRe: Get a "Fake" Handle? Pin
C. Augusto Proiete4-Aug-03 7:38
C. Augusto Proiete4-Aug-03 7:38 
GeneralRe: Get a &quot;Fake&quot; Handle? Pin
John M. Drescher4-Aug-03 7:57
John M. Drescher4-Aug-03 7:57 
AnswerRe: Get a &quot;Fake&quot; Handle? Pin
Joseph M. Newcomer14-Aug-03 7:17
Joseph M. Newcomer14-Aug-03 7:17 
GeneralRe: Get a "Fake" Handle? Pin
C. Augusto Proiete14-Aug-03 9:00
C. Augusto Proiete14-Aug-03 9:00 
GeneralRe: Get a &quot;Fake&quot; Handle? Pin
Anonymously16-Aug-03 22:17
Anonymously16-Aug-03 22:17 
Generalfile handle to file name Pin
Fad B26-Feb-03 7:55
Fad B26-Feb-03 7:55 
GeneralRe: file handle to file name Pin
Joseph M. Newcomer26-Feb-03 9:07
Joseph M. Newcomer26-Feb-03 9:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.