public function listItem($type, $dir = '.', $recursive = false, $ignore = array())
    {
        if ($type != 'dir' && $type != 'file') {
            throw new \InvalidArgumentException('$type must "file" or "dir"');
        }
        $fileList = $this->nList($dir);
        $fileInfo = array();
        foreach ($fileList as $file) {
            // remove directory and subdirectory name
            $file = str_replace("$dir/", '', $file);
            if ($this->ignoreItem($type, $file, $ignore) !== true && $this->isDirOrFile("$dir/$file") == $type) {
                $fileInfo[] = $file;
            }
            if ($recursive === true && $this->isDirOrFile("$dir/$file") == 'dir') {
                $fileInfo = array_merge($fileInfo, $this->listItem($type, "$dir/$file", $recursive, $ignore));
            }
        }
        return $fileInfo;
    }