Listing files in a directory without annoying the Finder

Hello,

I have a directory containing files with different types / extensions. I want to populate NSArrays with the files of each type, after some modifications on these files.

In order to work with less file access types (URL, path, HFSpath, alias and so on.), I’m trying to replace this:

tell application "Finder" to set aList to name of files in gCurrentFolder whose name extension is "atxt"
   repeat with theFile in theList
      -- do something with the .atxt file
   end repeat

with this:

set theList to manager's enumeratorAtPath_(gCurrentPath)'s allObjects()
set theFile to current application's NSString's |string|()
   repeat with theFile in theList
      if theFile's pathExtension() as string is ("atxt") then
         -- do something with the .atxt file
      end if
   end repeat

The code is a bit longer (and maybe slower?) : as I get ALL the files of the directory, I have to check the extension with IF. On the other side, if I have more than one file type /extension, I can sort them inside this IF, instead off calling the Finder again to list the files for each type.

I was wondering if there was a “filter” of some kind to extract from “theList” some sub-lists containing only the files with a particular extension.

More, if there was a more efficient way to use the NSFileManager / NSDirectoryEnumerator.

Thank you,

If you only want to go one level deep, use contentsOfDirectoryAtPath:error:, otherwise use subpathsOfDirectoryAtPath:error:. Then you can use NSPredicate to filter the results.

Thank you Shane,

Yes, there is only one level into my directory, so I shall send

    set theList to manager's contentsOfDirectoryAtPath_error_(gCurrentPath,missing value)

I didn’t know if a method was faster than the other (but of course with 200 files this could not be noticeable)

Is the use of NSPredicate worth it instead of an IF test?

Regards,

You tell me :slight_smile:

It probably is, but it may not be worth the effort. The main thing is to get out of the clutches of the Finder.

One can not escape so easily from the Finder. or from the type coercion. Imagine that the directory is empty:

set theList to manager’s contentsOfDirectoryAtPath_error_(gCurrentPath,missing value) – gives an empty NSArray (?)
set theList to manager’s contentsOfDirectoryAtPath_error_(gCurrentPath,missing value) as list – gives an empty AS list

I can test in the second case if theList is {}, but curiously not in the first. And theList’s |count| is 0 doesn’t work either. I suppose it is theList’s |count| as integer is 0, but I didn’t test it.

Or you can do : if (theList as list) is {} then

This coercion problem is always latent-- I think the best way is to coerce only when it’s strictly needed, not systematically. If I do:

set theList to manager’s contentsOfDirectoryAtPath_error_(gCurrentPath,missing value) as list

I transform theList into an AS list and then it may not work if I test its contents via other Cocoa calls. :confused:

That’s putting it politely.

I tend to agree. Then you can have your “vanilla” AS assume it always has to coerce.

But with the best will in the world, it can easily get fudged in complex projects.

Don’t forget the parentheses. This works


theList's |count|()

Another way to check whether an NSArray is empty is to test to see if lastObject() is missing value. objectAtIndex_(0) gives an out of bounds error, but lastObject returns nil if the array is empty.

Ric

Fiz,
in your example, the first one that “doesn’t work” is returning nil, since it’s ObjC. And Objective-C is OK with returning nil and doing operations on nil (or, not doing them as it were). Nil seems to be the same as “missing value”- you can’t test anything on it, and whatever you coerce it to in AS, just becomes an empty value of whatever kind you just tried to coerce.
Ric’s got the right idea.

No, Sir, if gCurrentPath is valid contentsOfDirectoryAtPath: returns always a (NS)array,
which is empty if the directory is empty