Movatterモバイル変換


[0]ホーム

URL:


Legacy Documentclose button

Important:The information in this document is obsolete and should not be used for new development.

PreviousBook ContentsBook IndexNext


Locking and Unlocking File Ranges

A file can be opened with shared read/write permission to allow several users to share the data in the file. When a user needs to modify a portion of a file that has been opened with shared read/write permission, it is usually desirable to make that portion of the file unavailable to other users while the changes are made. You can call thePBLockRange function to lock a range of bytes before modifying the file and thenPBUnlockRange to unlock that range after your changes are safely recorded in the file.

Locking a range of bytes in a file gives the user exclusive read/write access to that range and makes it inaccessible to other users. Other users can neither write nor read the bytes in that range until you unlock it. If other users attempt to read data from a portion of a file that you have locked, they receive thefLckdErr result code.

The functionsPBLockRange andPBUnlockRange are effective only on files that are located on volumes that are sharable. If you callPBLockRange on a file that is not located on a remote server volume or that is not currently being shared, no range locking occurs. Moreover,PBLockRange does not return a result code indicating that no range locking has occurred. As a result, you should usually check whether range locking will be effective on a file before attempting to lock the desired range.

Listing 2-9 illustrates how you can check to make sure that callingPBLockRange will have the desired effect.

Listing 2-9Determining whether a file can have ranges locked

FUNCTION RangesCanBeLocked (fRefNum: Integer): Boolean;VAR   myParmBlk:  ParamBlockRec;             {basic parameter block}   myErr:      OSErr;BEGIN   WITH myParmBlk DO      BEGIN         ioRefNum := fRefNum;         ioReqCount := 1;                 {lock a single byte}         ioPosMode := fsFromStart;        {at the beginning of the file}         ioPosOffset := 0;      END;   myErr := PBLockRange(@myParmBlk, FALSE);{lock the byte; ignore result}   myErr := PBLockRange(@myParmBlk, FALSE);{lock the byte again}   CASE myErr OF      fLckdErr,                           {byte was locked by another user}      afpRangeOverlap,                    {byte was locked by this user}      afpNoMoreLocks:                     {max number of locks already used}         BEGIN            RangesCanBeLocked := TRUE;    {range locking is supported}            IF myErr = afpRangeOverlap THEN  {unlock the byte we locked}               myErr := PBUnlockRange(@myParmBlk, FALSE);         END;      OTHERWISE         RangesCanBeLocked := FALSE;      {range locking is not supported}   END; {of CASE}END;
The function RangesCanBeLocked takes a file reference number of an open file as
a parameter; this is the reference number of the file in which a range of bytes is to
be locked. The function attempts to locks the first byte in the file and immediately
attempts to lock it again. If the second range locking fails with the result codeafpRangeOverlap, the first call toPBLockRange was successful. If the second call toPBLockRange fails with the result codefLckdErr, the byte was already locked by another user. Similarly, if the second call toPBLockRange fails with the result codeafpNoMoreLocks, the maximum number of range locks has been reached. In these three cases, range locking is supported by the volume containing the specified file. If any other result code (includingnoErr) is returned, range locking is not supported by that volume or for some reason the capabilities of the volume cannot be determined.

Note
Local file sharing can be started or stopped (via the Sharing Setup control panel) while your application is running. For this reason, each time you want to lock a range, it's best to check that byte ranges in that file can be locked.
You can unlock a locked range of bytes by callingPBUnlockRange. Note that the range to be unlocked must be the exact same range of bytes that was previously locked usingPBLockRange. (You can lock and unlock different byte ranges in any order, however.) If for some reason you need to unlock a range of bytes and do not know where the range started or how long the range is, you must close the file to unlock the range. When a file is closed, all locked ranges held by a user are unlocked.

If you want to append data to a shared file, you can usePBLockRange to lock the range of bytes from the file's current logical end-of-file to the last possible addressable byte of the file. Once you have locked that range, you can write data into it.Listing 2-10 shows how to determine the current logical end-of-file and lock the appropriate range.

Listing 2-10Locking a file range to append data to the file

FUNCTION LockRangeForAppending (fRefNum: Integer; VAR EOF: LongInt): OSErr;VAR   myParmBlk:  ParamBlockRec;             {basic parameter block}   myErr:      OSErr;   myEOF:      LongInt;                   {current EOF}BEGIN   myParmBlk.ioCompletion := NIL;   myParmBlk.ioRefNum := fRefNum;   myErr := PBGetEOF(@myParmBlk, FALSE);  {get the current EOF}   IF myErr <> noErr THEN      BEGIN         LockRangeForAppending := myErr;         Exit(LockRangeForAppending);     {trouble reading EOF}      END;   myEOF := LongInt(myParmBlk.ioMisc);    {save the current EOF}   WITH myParmBlk DO      BEGIN         ioReqCount := -1;                {all addressable bytes}         ioPosMode := fsFromStart;        {start range...}         ioPosOffset := myEOF;            {...at the current end-of-file}      END;   myErr := PBLockRange(@myParmBlk, FALSE);{lock the specified range}   EOF := myEOF;                          {return current EOF to caller}   LockRangeForAppending := myErr;END;
The functionLockRangeForAppending first determines the current logical end-of-file. It is important to get this value immediately before you attempt to lock a range that depends on it because another user of the shared file might have changed the end-of-file since you last read it. ThenLockRangeForAppending locks the range beginning at the current end-of-file and extending for the maximum number of bytes (specified using the special value -1).

In effect, this technique locks a range where data does not yet exist. Practically speaking, locking the entire addressable range of a file prevents another user from appending data to the file until you unlock that range. Note thatLockRangeForAppending returns the current logical end-of-file to the caller so that the caller can unlock the correct range of bytes after appending the data.

You can also callPBLockRange to lock a range of bytes when you want to truncate a file. Locking the end portion of a file to be deleted prevents another user from using that portion during the truncation. Instead of setting theioPosOffset field of the parameter block to the logical end-of-file (as inListing 2-10), simply set it to what will be the last byte after the file is truncated. Similarly, you can lock an entire file fork by setting theioPosOffset field to 0.


PreviousBook ContentsBook IndexNext

Shop theApple Online Store (1-800-MY-APPLE), visit anApple Retail Store, or find areseller.

Copyright © 2016 Apple Inc. All rights reserved.


[8]ページ先頭

©2009-2025 Movatter.jp