The BFile
that you
pass in is copied by the BResources
object. Thus,
initializing a BResources
object opens a new file descriptor into the
file. You can delete the "original"
BFile
immediately after you use it
to initialize the BResources
object.
Care must be taken to avoid writing to a
BFile
that other
applications have open for reading. BResources
can't enforce this rule,
but if you're not careful to abide by it, problems can (and will)
occur. Likewise, multiple applications mustn't open the same file for
writing at the same time.
If you want to write resources, the
BFile
must not be locked when you
pass it in. The BResources
needs to be able to lock its copy of your
object.
The BFile
must be open for reading (at least).
Unfortunately, BResources
lacks an
InitCheck()
function. If you want
to check initialization errors, you should always initialize through
SetTo()
,
rather than through the constructor.
Identifying and Creating Resource Files
You can't use just any old file as a BResources
initializer: The file
must be an actual resource file. Simply initializing a BResources
object
with an existing non-resource file will not transform the file into a
resource file—unless you tell the initializer to clobber the
existing file.
For example, this initialization fails:
/* "fido" exists, but isn't a resource file. */
BFile
file
("/boot/home/fido", B_READ_WRITE
);
BResources
res
;
status_t err
;
if ((err
= res
.SetTo
(&file
)) != B_OK
)
...
And this one succeeds…
/* The second arg to SetTo() is the "clobber?" flag. */
if ((err
= res
.SetTo
(&file
, true
)) != B_OK
)
...
…but at a price: fido's existing data is destroyed (truncated to 0
bytes), and a new "resource header" is written to the file. Having gained
a resource header, fido can thereafter be used to initialize a BResources
object.
Clobber-setting a resource file is possible, but, as mentioned at the top
of this class description, you'll probably never create resource files
directly yourself
So where do resource files come from if you don't create them yourself?
Step right up…
Executables as Resource Files
The only files that are naturally resource-ful are application
executables. For example, here we initialize a BResources
object with the
IconWorld executable:
BPath
path
;
BFile
file
;
BResources
res
;
find_directory
(B_APPS_DIRECTORY
, &path
);
path
.Append
("IconWorld");
file
.SetTo
(&path
, B_READ_ONLY
);
if (res
.SetTo
(&file
) != B_OK
)
...
The BResources
object is now primed to look
at IconWorld's resources. But
be aware that an application's "app-like" resources (its icons,
signature, app flags) should be accessed through the
BAppFileInfo
class.