This is somewhat hideous.  We double the array, and then later we contract it back to the exact size necessary.  Makes me wonder if returning an immutable List<DirEnt> might be better, because then we don't need to contract the result array back to the correct size.  Unfortunately walking the List<DirEnt> would require allocating an Iterator<DirEnt>, so its an object allocation either way.