The Code Project View our sponsorsClick here for Dundas Consulting - experts in MFC, C++, TCP/IP and ASPAdvertise on the CodeProject
Home >> Files & Folders >> General

A Handy Guide To Handling Handles
By Joseph M. Newcomer

The secrets of File Handles and their relationship to File *, CFile, CStdioFile, etc. 
 VC6, Win9x, NT4, MFC
 Posted 5 Apr 2001
Articles by this author
Send to a friend
Printer friendly version
Lounge New Articles Sign in Forums Contribute
Broken links? Email us!
7 users have rated this article. result:
4 out of 5.

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. 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.

From To
HANDLE C Library handle
HANDLE CFile
C Library handle HANDLE
C Library handle FILE *
FILE * C Library handle
FILE * CStdioFile
CFile HANDLE
CStdioFile FILE *
stdxxx HANDLE

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.

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>
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.

FILE * to C Library handle

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

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

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.

Summary of File Handle Transformations

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. 

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);

CStdioFile to FILE *

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

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.

CStdioFile file(myfile);

or

CStdioFile * file = new CStdioFile(myfile);

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.

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
http://www.pgh.net/~newcomer/mvp_tips.htm

[Top] Sign in to vote for this article:     PoorExcellent  
Hint: For improved responsiveness, use Internet Explorer 4 (or above) with Javascript enabled, choose 'Use DHTML' from the View dropdown and hit 'Set Options'.
 Keyword Filter
 View   Per page   Messages since
New threadTotal Messages for this article: 0 
Subject 
Author 
Date 
-- No entries present --

Home >> Files & Folders >> General
last updated 5 Apr 2001
Article content copyright Joseph M. Newcomer, 2001
everything else © CodeProject, 1999-2001.
The Code Project View our sponsorsGet the power of C++ with the ease of VBAdvertise on the CodeProject