Recipe 12.19. Opening a File Stream with Just a File HandleProblemWhen interoperating with unmanaged code, you encounter a situation in which you are provided a file handle and no other information. This file handle must be used to open its corresponding file. SolutionIn order to use an unmanaged file handle to access a file, use the FileStream class. The unmanaged file handle could have been generated using P/Invoke to open a file and get the file handle. The code would then use a FileStream object for writing data, then flush and close the unmanaged file handle. This setup is illustrated by the UsingAnUnmanagedFileHandle method shown in Example 12-8. Example 12-8. UsingAnUnmanagedFileHandle method
In the UsingAnUnmanagedFileHandle method, we wrap the file handle in a SafeFileHandle object and pass it as the first parameter, in a FileStream. Once we have the file stream, we use its capabilities to write to the file handle. We get the bytes from a string in ASCII-encoding format and call Write on the file stream, as shown here: byte[] bytes = Encoding.ASCII.GetBytes(line); fileStream.Write(bytes,0,bytes.Length); In order to perform the unmanaged functions of creating, flushing, and closing the file handle, we have wrapped the unmanaged Win32 API functions for these functions in the FileInteropFunctions class shown in Example 12-9. The DllImport attribute says that these functions are being used from kernel32.dll and the SetLastError attribute is set to true, so that we can see if anything went wrong. A few of the #defines used with file creation have been brought over from unmanaged code for readability. Example 12-9. FileInteropFunctions class
DiscussionYou can open a file using one of the overloaded constructors of the FileStream class and passing a file handle into it. The FileStream constructors in Version 2.0 of the .NET Framework have been enhanced to accept a Microsoft.Win32.SafeHandles. SafeFileHandle object instead of an IntPtr for the file handle. The SafeFileHandle wraps the IntPtr file handle and allows the system to handle the releasing of this file handle automatically. To automatically release this wrapped file handle, you must pass true as the second argument to the SafeFileHandle constructor. Microsoft recommends letting the system handle the releasing of this wrapped file handle. Keep your code short when opening a file using a file handle. Call the FileStream. Close method as soon as possible or use the using statement as in the Solution for this recipe. One reason for this recommendation is that another object might also have this file open, and operating on that file through both FileStream objects can corrupt the data in the file. See AlsoSee the "DllImport Attribute," "File Class," and "FileStream Class" topics in the MSDN documentation. |