FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

DISK I/O

Catalog files


The following code is a small snip from MacSlack (http://www.pobox.com/~ericb/software/macslack), with slight modification to illustrate dealing with file types, since the full discussion of those fields of the paramater block are not discussed directly in IM:Files. The full source for MacSlack is available; see the web page for more info.

'scan the folder with id number dirID& on volume vref%
'note that a volume's root directory is always 2, so you can start with that
LOCAL FN SearchFolder (vref%,dirID&)
  DIM param$,indxCount,pbPtr&,fname$,strPtr&,oserr%

'what file in the directory are we examining?
  indxCount = 1

  pbPtr&=@param$
  strPtr&=@fname$

  pbPtr&.ioFDirIndex% = indxCount 'if 3, GetCatInfo returns info on third item in the directory
  pbPtr&.ioDirID& = dirID&
  pbPtr&.filler2& = 0
  pbPtr&.ioVrefnum% = vref%
  pbPtr&.ioNamePtr& = strPtr&

'see Inside Mac: Files; note that PHGetCatInfo overwrites the ioDirID field
  osErr = FN GETCATINFO (pbPtr&) 'the IM:Files name for this call is PBGetCatInfo

  LONG IF osErr = _noErr
    LONG IF FN BITTST (pbPtr&.ioFlAttrib%, _kFolderBit)
'you found a folder; add it to your directory scanning queue for later processing or
'recursively call this function immediately to scan it
    XELSE
'you found a file; you can get info on it or do whatever you want to do here
'for example, this lets you change the creator type:

      pbPtr&.ioFlUsrWds.fdCreator&=OSType1&
      pbPtr&.ioFlUsrWds.fdType&=OSType2&

      pbPtr&.ioDirID& = dirID& 'reset dirID that GetCatInfo overwrote
      oserr%=FN SETCATINFO (pbPtr&)

    END IF
XELSE
'handle the error
END IF

END FN

Eric Bennett


I have a boat load of graphics files of a specific type/creator that I want to catalog. I've been able to use the GETCATINFO to find these files in a folder (single level deep; I don't need recurrsive searching since I may want to only catalog certain folders of files). However this merely returns the filename.

So what is the absolute minimum space in bytes I need to store this kind of file information if I wanted to be able to go back later and re-open a specific graphic file?

Disk space used to hold this "catalog listing" is going to be very important so I want to keep it as small as I can. I figure I have about 3000+ files to catalog. Some on CD, Zip and some on my HD. So they may not always be online at any one point in time.

As usual, nudges, advice and wiggy words of wisdom all appreciated...code not usually required (I can write some of the best buggy code without even trying anymore)...

-------- Speaking of GETCATINFO ----------

My routine to read the filenames of my images works :

LOCAL FN getDesignNames(howMany,fromWhere)
  DIM PBlock$
  DIM 63 FName$
  DIM 7 Type$
  DEF BLOCKFILL(@PBlock$,255,0):' fill block with zeros
  & @PBlock$+_IoNamePtr,@FName$:' stuff it into the parameter block
  FileIndex=fromWhere:' this is the starting index point
  IncludeNum=0:' where the file info gets stuffed
  DO
    % @PBlock$+_IoFDirIndex,FileIndex:' start looking through the list
    % @PBlock$+_ioVRefNum,designVol:' and see what we can find
    OSErr=FN GETFILEINFO(@PBlock$):' get file information on this file
    FileType&=[@PBlock$+_IoFlUsrWds_FdType]:' *** File Type ***
    FileDad& =[@PBlock$+_IoFlUsrWds_FdCreator]:' *** File Creator ***
    LONG IF OSErr=0
      SELECT FileDad&:' see which program created our file type
        CASE _"PCDA":' was it created by ZBASIC
          SELECT FileType&:' now we have to check the type
            CASE _"PCS "
              INC(IncludeNum):' storing them in the array now
              designName$(IncludeNum)= FName$
          END SELECT
      END SELECT
    END IF
    INC(FileIndex)
  UNTIL OSErr OR IncludeNum > howMany
END FN = IncludeNum

I get a filename. Not a pathname. Now logic tells me I "should" be able to determine the PARENTID from this routine too. So I tried it use one of the GetDirID functions that most of us use with alias records...I get a dirID from it.

My second thought was that I could use the FB PARENTID command and pass it the DIRID I got to reset to the original folder if I want to read another file from it. Nada. But you already knew that didn't you...

My third and final thought is that I am going to ask because so far, I am 0 for 2 and I hate to strike out....

Mel Patrick


How much "later" is later? If you intend to re-open the files "soon" (that is, while their volumes are still mounted), then it's sufficient to keep the following info about the file:

file name (not path);
directory ID of its parent;
volume reference number of the volume it's on.

But this system may break down if you intend to access the file again after you've shut down & restarted, or after you've unmounted the file's volume. That's because volume reference numbers are dynamically re-assigned every time a volume is re-mounted. Your permanently-connected hard disks will _probably_ get the same ref. number each time, but even that's not guaranteed.

The recommended way to keep track of a file over time is to use aliases. They'll keep track even if the file's volume is not currently mounted (the Alias Manager will even automatically ask for the disk to be inserted if it's not online).

But aliases may require more disk space than you're willing to spare. The next best way, then, might be to store this info for each file:

file name (not path);
directory ID of its parent;
volume name of the volume it's on.

IF you're certain that all your disks will have unique names, then this
should work.

<< -------- Speaking of GETCATINFO ----------
My routine to read the filenames of my images works :
I get a filename. Not a pathname. Now logic tells me I "should" be able to determine the PARENTID from this routine too. So I tried it use one of the GetDirID functions that most of us use with alias records...I get a dirID from it. >>

You don't need to call another function to get the parent's directory ID: it's returned by GETCATINFO along with the file's name:

theParent& = [@PBlock$ + _ioFlParID]

<< My second thought was that I could use the FB PARENTID command and pass it the DIRID I got to reset to the original folder if I want to read another file from it. Nada. But you already knew that didn't you... >>

The parent directory ID is unique within a single volume, but it's not unique across multiple volumes. In other words, volume "ABC" might contain a directory whose ID is 1255, and volume "XYZ" might also contain a directory whose ID is 1255. So specifying PARENTID = 1255 won't do you any good unless you also specify the volume in some way. If you're talking about FB's OPEN statement, then you can specify the volume as a (true) volume reference number in the vRefNum% parameter.
For example:

PARENTID = theParent&
OPEN "I", theFile$,,,vRefNum%

Now the only question is, "how do you _get_ the volume reference number?" As stated above, the "old" reference number is no good after the volume's been unmounted and re-mounted. There are different ways to get it; the answer depends on what form you finally decide to use to store your catalog.

Rick


I did something like what Mels wants to do:

For each file I want to remember, I create a FSSpec record, and to remember the volume I create an alias. I save all the FSSpec records as a linked list in a file and add the alias as a resource to the file's rsrc fork.
This lets me keep the FSSpecs and their alias together. To later access the file, I resolve the alias to the volume. This gets the user to do the dirty work finding and identifying the volume, if it isn't mounted (CD-ROMs, etc). Once FN RESOLVEALIAS tells me that the volume is available then I continue with accessing the file

Pete...


That sounds like a great idea. Since it sounds like Mel's files will be many to a single volume, he need only save one alias per many FSSpec's.

Great suggestion!

Rick