Retired Document
Important: This document is replaced by File System Programming Guide.
File Handle
NSFileHandle
objects provide an object-oriented wrapper for accessing open files or communications channels.
Overview
An NSFileHandle
is an object that represents an open file or communications channel. It enables programs to read data from or write data to the represented file or channel. You can use other Cocoa methods for reading from and writing to files—NSFileManager
’s contentsAtPath:
and NSData
’s writeToFile:options:error:
are but a couple of examples. Why would you use NSFileHandle
then? What are its advantages?
NSFileHandle
gives you greater control over input/output operations on files. It allows more manipulative operations on and within open files, such as seeking, truncating. and reading and writing at an exact position within a file (the file pointer). Other methods read or write a file in its entirety; withNSFileHandle
, you can range over an open file and insert, extract, and delete data.The scope of
NSFileHandle
is not limited to files. It provides the only Foundation object that can read and write to communications channels such as those implemented by sockets, pipes, and devices.NSFileHandle
makes possible asynchronous background communication. With it a program can connect to, and read from, a socket in a separate thread. (See Background Inter-Process Communication Using Sockets below for details on how this is done.)
Instances of NSPipe
, a class closely related to NSFileHandle
, represent pipes: unidirectional interprocess communication channels. See the NSPipe
reference for details.
Creating a File Handle Object
NSFileHandle
is a class clusters, file handle objects are not actual instances of the NSFileHandle
class but of one of its private subclasses. Although a file handle object’s class is private, its interface is public, as declared by the abstract superclass NSFileHandle
.
Generally, you instantiate a file handle object by sending one of the fileHandle...
messages to the NSFileHandle
class object. These methods return a file handle object pointing to the appropriate file or communications channel. As a convenience, NSFileHandle
provides class methods that create objects representing files and devices in the file system and that return objects representing the standard input, standard output, and standard error devices. You can also create file handle objects from file descriptors (such as found on BSD systems) using the initWithFileDescriptor:
and initWithFileDescriptor:closeOnDealloc:
methods. If you create file handle objects with these methods, you “own” the represented descriptor and are responsible for removing it from system tables, usually by sending the file handle object a closeFile
message.
Background Inter-Process Communication Using Sockets
Sockets are full-duplex communication channels between processes either local to the same host machine or where one process is on a remote host. Unlike pipes, in which data goes in one direction only, sockets allow processes both to send and receive data. NSFileHandle
facilitates communication over stream-type sockets by providing mechanisms run in background threads that accept socket connections and read from sockets.
NSFileHandle
currently handles only communication through stream-type sockets. If you want to use datagrams or other types of sockets, you must create and manage the connection using native system routines.
The process on one end of the communication channel (the server) starts by creating and preparing a socket using system routines. These routines vary slightly between BSD and non-BSD systems, but consist of the same sequence of steps:
Create a stream-type socket of a certain protocol.
Bind a name to the socket.
Adding itself as an observer of
NSFileHandleConnectionAcceptedNotification
.Sending
acceptConnectionInBackgroundAndNotify
to this file handle object. This method accepts the connection in the background, creates a newNSFileHandle
object from the new socket descriptor, and posts anNSFileHandleConnectionAcceptedNotification
.
In a method implemented to respond to this notification, the server extracts the NSFileHandle
object representing the “near” socket of the connection from the notification’s userInfo dictionary; it uses the NSFileHandleNotificationFileHandleItem
key to do this.
Typically the other process (the client) then locates the named socket created by the first process. Instead of accepting a connection to the socket by calling the appropriate system routine, the client creates an NSFileHandle
object using the socket identifier as argument to initWithFileDescriptor:
.
The client can now send data to the other process over the communications channel by sending writeData:
to the NSFileHandle
instance. (Note that writeData:
can block.) The client can also read data directly from the NSFileHandle
, but this would cause the process to block until the socket connection was closed, so it is usually better to read in the background. To do this, the process must:
Add itself as an observer of
NSFileHandleReadCompletionNotification
orNSFileHandleReadToEndOfFileCompletionNotification
.Send
readInBackgroundAndNotify
orreadToEndOfFileInBackgroundAndNotify
to thisNSFileHandle
object. The former method sends a notification after each transmission of data; the latter method accumulates data and sends a notification only after the sending process shuts down its end of the connection.In a method implemented to respond to either of these notifications, the process extracts the transmitted or accumulated data from the notification’s userInfo dictionary by using the
NSFileHandleNotificationDataItem
key.If you wish to keep getting notified you’ll need to again call
readInBackgroundAndNotify
in your observer method.
You close the communications channel in both directions by sending closeFile
to the NSFileHandle
object; either process can partially or totally close communication across the socket connection with a system-specific shutdown command.
Copyright © 1997, 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-05-25