Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 42
Текст из файла (страница 42)
It is, however, inefficientto make multiple calls to a server function, so RDir also supplies anoverload of Read() that, in a single call, reads several entries into aTEntryArray. The number of entries contained in each TEntryArraycannot be determined before a call to Read() because the length ofeach file or directory name is likely to be different. As with many otherfunctions that involve communication with a server, two further overloadssupply asynchronous versions of the two types of Read(), to be usedfrom an active object.In addition to RDir’s Read() functions, RFs provides a range ofGetDir() functions that, in a single call, reads an entire directory’scontent, or all entries matching the search criteria, into a CDir.
This cansimplify reading a directory contents, however, it still makes use of RDirand so may be less efficient than a function written for the requirementsof particular application.As you can see from the following code, which creates a list of entriessimilar to that of the previous example, GetDir() also allows you tospecify a sort order for the resulting list.void ReadDirContentsL(RFs& aFs, const TDesC& aDirName){CDir* dirList;User::LeaveIfError(aFs.GetDir(aDirName, KEntryAttNormal,ESortByName, dirList));// Process the entriesdelete dirList;}You can change the attributes of directory entries, including thehidden, system, read-only and archive bits.
The only bit with a reallyunambiguous meaning is read-only. If a file is specified as read-only, thenyou cannot write to it or erase it. The other attributes are supported forstrict compatibility with VFAT but they are not important in Symbian OS,so it is probably best not to use them.Symbian OS maintains directory entry timestamps in UTC, not localtime, so that there is no risk of confusion caused by a time zone change.All time parameters are returned by the file server in UTC; it is a task forthe application writer to convert them to local time.FILE SYSTEM SERVICES211FilesWithin a file server session, an individual file is represented by an RFileobject, which provides the means of opening and manipulating the file.For example, to open a file and append data to it, you could use thefollowing code:TInt WriteToFileL(RFs& aFs, const TDesC& aFileName, const TDesC8& aData){RFile file;TInt err = file.Open(aFs, aFileName, EFileWrite);if (err == KErrNotFound) // file does not exist, so create it{err = file.Create(aFs, aFileName, EFileWrite);}User::LeaveIfError(err);CleanupStack::CleanupClosePushL(file);User::LeaveIfError(file.Seek(ESeekEnd, 0));User::LeaveIfError(file.Write(aData));CleanupStack::PopAndDestroy() ; // Closes the file}This code attempts to open an existing file, but if the file does not exist,it is created.
In addition to Open() and Create(), RFile provides twoother means of opening a file:• Replace(), which deletes an existing file and creates a new one• Temp(), which opens a temporary file and allocates a name to it.In the example above, the file is opened as a binary file, with nonshared write access. A file can be opened as a text file and a variety ofother access modes are supported, including shared write and exclusiveor shared read.
The mode indicators can be divided into the followinglogical groups. Subject to the specific restrictions stated below, thefile mode is specified by ORing together up to one value from eachgroup.• Read or write access:◦ EFileRead: The file is opened for reads but not writes.◦ EFileWrite: The file is opened for reads or writes; this mode isnot compatible with EFileShareReadersOnly.• Text or binary:◦ EFileStream: The file is opened in binary mode; this is thetypical case for native Symbian OS applications.◦ EFileStreamText: The file is opened in text mode.212FILES AND THE FILE SYSTEM• Shared access:◦ EFileShareExclusive: If the file is opened with this mode,no other program can access the file until it is closed. If the filehas already been opened by another application, in any mode,attempting to open the file in this mode will fail.◦ EFileShareReadersOnly: The file may be opened by othersonly for reading. This flag is incompatible with EFileWrite.◦ EFileShareAny: The file may be shared with others for readingand writing.
This flag is incompatible with EFileShareReadersOnly.◦ EFileShareReadersOrWriters: The file may be shared forreading and writing. In this mode, the file does not care if it isopened for reading or writing. It is compatible with files openedwith EFileShareReadersOnly.• Read completion:◦ EFileReadAsyncAll: Read requests should not complete untilall requested data becomes available.
This flag cannot be combined with EFileShareExclusive or EFileShareReadersOnly as this would prevent other clients writing data to the file.If you don’t specify otherwise, a file is, by default, opened as a binaryfile, with no shared access.You normally specify the access mode when you open the file, althoughyou can use ChangeMode() to change it while the file is open. Youmust have appropriate capabilities to change the access mode of the file.When a file is opened by more than one process with shared write access,you can use Lock() to claim temporary exclusive access to a region ofthe file and UnLock() it after the update is made.When a file is first opened, the current read and write position is set tothe start of the file.
You can use Seek() to move to a different position;the code example above uses it to move to the end of the file, ready toappend more data. RFile provides a variety of overloaded Write()functions, all of which write 8-bit data from a TDesC8. Half of them aresynchronous functions, such as the one used in the above example andthe others are asynchronous, for use from an active object.There is a corresponding variety of overloaded Read() functions,again supplied in both synchronous and asynchronous versions, all ofwhich read 8-bit data into a TDes8.There is also provision for opening a file in a mode designed forstreaming media, EFileReadAsyncAll.
This mode allows the file tohave an outstanding read operation beyond the current length of the file.A read operation for a file opened in this mode cannot complete untilsufficient data has been written to file. Corresponding functions exist toFILE SYSTEM SERVICES213allow reads that may not complete (for example, if the length of streameddata is unknown) to be canceled. Also note that only this type of readoperation can be canceled; conventional asynchronous file reads andwrites cannot be canceled.Unless you are reading or writing fairly small amounts of information,you should always use the asynchronous functions to ensure that theapplication remains responsive during potentially long read or writesequences.Sharing File HandlesFor file data that may be shared between more than one application thereare several approaches you could take.
First, the file containing the datacould be created in a public area of a file system. This is a legitimateplace to store a file, however it offers no protection to the data stored in.Any other application can open the file and read its contents.The second approach is suitable for a set of applications that sharedata stored in files. The application that ‘owns’ the data can createa file in its own private directory, as mentioned above. To share thedata with another application, a handle to this file may be shared.
Thisrequires that application X provides an API that application Y can call.The API implemented by application X returns a handle to the shared file.Application Y can then use this handle to access the data contained inthe file.File-sharing APIs are provided in the RFile class. One process mustact as a server, the other as a client.
This is normally a simple decisionas one process or application is likely to own a file that another processrequests access to, although files can be shared in either direction.In the example below, the server process opens the file with the accessmode it wishes the client to use. The server then transfers the handle tothe client via an IPC call, specifying the message number in which thehandle is stored.GetFileHandleWriteL(RFs& afs, const RMessage2& aMsg){User::LeaveIfError(afs.ShareProtected() );RFile file;User::LeaveIfError(file.Open(afs, KFileName, EFileWrite));CleanupStack::CleanupClosePushL(file);User::LeaveIfError(file.TransferToClient(aMsg, 0));CleanupStack::PopAndDestroy() ; // results in RFile::Close()aMsg.Complete(r);}In the above code, the file is shared with write access and is passedto the client.
The file server session against which the file is opened isalso shared. This session must have SharedProtected() called on itfirst, to allow the RFs to be used by a process other than the one which214FILES AND THE FILE SYSTEMopened it. The file handle is duplicated as part of the sharing processwhich means that the file-sharing server can call Close() on the file ifit no longer requires it open.