删除指定的文件或目录，如果删除后父目录为空也会删除父目录

@param string $path 要删除的文件的路径
@param string $isfull 路径是否为完整路径
@param string $fsencoding 文件系统的编码，如不为空则会自动进行一些编码转换
338096
public static function delete($path, $isfull = false, $fsencoding = '') {
        $path = strval($path);
        if ($path == '') {
            return;
        }
        if (!$isfull) {
            $path = WEB_ROOT . $path;
        }

        $path = self::conv_to($path, $fsencoding);

        $parent = dirname($path);
        if (file_exists($path)) {
            if (is_dir($path)) {
                rmdir($path);
            }
            else {
                @unlink($path);
            }
            if (self::dir_empty($parent)) {
                self::delete($parent, true);
            }
        }
    }
451385
protected static function normalizerPath($path, $is_dir = false)
    {
        $path = ltrim(PathLibrary::normalizerPath($path, $is_dir), '/');

        return $path == '/' ? '' : $path;
    }
346767
private function file_or_dir($path, $is_file) {
        assert(is_bool($is_file));
        $obj = $this->get($path);
        if ($obj !== null && $is_file === $obj->isFile()) {
            return $obj;
        }
        return null;
    }
809848
public function createFile($path, $contents)
    {
        $path = str_replace(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $path);

        $this->_io->out();

        $fileExists = is_file($path);
        if ($fileExists && empty($this->params['force']) && !$this->interactive) {
            $this->_io->out('<warning>File exists, skipping</warning>.');

            return false;
        }

        if ($fileExists && $this->interactive && empty($this->params['force'])) {
            $this->_io->out(sprintf('<warning>File `%s` exists</warning>', $path));
            $key = $this->_io->askChoice('Do you want to overwrite?', ['y', 'n', 'a', 'q'], 'n');

            if (strtolower($key) === 'q') {
                $this->_io->out('<error>Quitting</error>.', 2);
                $this->_stop();

                return false;
            }
            if (strtolower($key) === 'a') {
                $this->params['force'] = true;
                $key = 'y';
            }
            if (strtolower($key) !== 'y') {
                $this->_io->out(sprintf('Skip `%s`', $path), 2);

                return false;
            }
        } else {
            $this->out(sprintf('Creating file %s', $path));
        }

        $File = new File($path, true);

        try {
            if ($File->exists() && $File->writable()) {
                $File->write($contents);
                $this->_io->out(sprintf('<success>Wrote</success> `%s`', $path));

                return true;
            }

            $this->_io->err(sprintf('<error>Could not write to `%s`</error>.', $path), 2);

            return false;
        } finally {
            $File->close();
        }
    }
412398
public function extfile($path){
        $rtn["fullfilename"] = substr(strrchr($path, "/"), 1);
        $rtn["ext"] = substr(strrchr($path, "."), 1);
        $rtn["filename"] = substr($rtn["fullfilename"], 0, -(strlen($rtn["ext"])+1));
        return $rtn;
     }
253696
protected function fcloseCE($fp, $path='') {
		return (!$this->encoding)? $this->_fclose($fp, $path) : $this->convEncOut($this->_fclose($fp, $this->convEncIn($path)));
	}
82155
public static function call($func, $full, $fsencoding = '') {
        if (function_exists($func)) {
            $full = self::conv_to($full, $fsencoding);
            return $func($full);
        }
        return false;
    }
1118513
public function getContents($path)
    {
        $fullPath = $this->concatPaths($path);

        if (file_exists($fullPath)) {
            return file_get_contents($fullPath);
        }

        return false;
    }
14858
private function needsInitialNewline($path)
    {
        $result = false;
        if (! file_exists($path)) {
            return $result;
        }
        $fh = fopen($path, 'r');
        if ($fh === false) {
            return $result;
        }
        if (fseek($fh, -1, SEEK_END) === 0) {
            $lastChar = fgetc($fh);
            if ($lastChar !== "\n" && $lastChar !== "\r") {
                $result = true;
            }
        }
        fclose($fh);
        return $result;
    }
516978
public static function scanDirs($path, $onlyLevel = false, $lvl = 0)
    {
        static $res;

        if ($lvl == 0) {
            $res = [];
        }

        if (!is_dir($path)) {
            return [];
        }

        if (substr($path, -1) == '/') {
            $path = substr($path, 0, -1);
        }
        $dir_base_length = strlen(DIR_BASE) - 1;

        foreach (array_diff(scandir($path), ['.', '..']) as $f) {
            if (is_dir($path . '/' . $f)) {
                if (!$onlyLevel) $res[] = [
                    'path_url' => substr($path, $dir_base_length),
                    'path'     => $path,
                    'name'     => $f,
                    'full'     => $path . '/' . $f,
                    'fs'       => 0,
                    'type'     => 'dir'
                ];
                self::scanDirs($path . '/' . $f, $onlyLevel, $lvl + 1);
            } elseif ($onlyLevel) {
                $res[] = $path . '/' . $f;
            } else {
                $res[] = [
                    'path_url' => substr($path, $dir_base_length),
                    'path'     => $path,
                    'name'     => $f,
                    'full'     => $path . '/' . $f,
                    'fs'       => filesize($path . '/' . $f),
                    'type'     => 'file'
                ];
            }
        }

        if ($lvl == 0) {
            return $res;
        }

        return [];
    }
1279696
public function fileGetContents($path)
    {
        if (! $this->isFile($path))
            return false;
        return $this->at($path)->content;
    }
155955
public static function copy_dir($src, $dest, $hidden = false, $fsencoding = '') {
        $src = strval($src);
        if ($src == '') {
            return;
        }
        $src = self::conv_to($src, $fsencoding);
        $dest = self::conv_to($dest, $fsencoding);
        self::mkdir($dest);
        if (!\is_dir($dest) || !\is_dir($src)) {
            return;
        }
        if (substr($src, -1) !== '/') {
            $src .= '/';
        }
        if (substr($dest, -1) !== '/') {
            $dest .= '/';
        }
        if ($dh = opendir($src)) {
            while (($file = readdir($dh)) !== false) {
                if ($file === '.' || $file === '..') {
                    continue;
                }
                if ($file{0} == '.' && !$hidden) {
                    continue;
                }
                $from = $src . $file;
                $to = $dest . $file;
                if (is_dir($from)) {
                    self::copy_dir($from, $to, $hidden);
                }
                else {
                    self::copy($from, $to);
                }
            }
            closedir($dh);
        }
    }
277193
private function setPath($path)
    {
        $this->info['path'] = $this->info['file'] = $this->info['extension'] = $this->info['content'] = null;

        if ($this->getScheme() === 'data') {
            $this->info['content'] = $path;

            return;
        }

        $file = substr(strrchr($path, '/'), 1);

        if (strlen($file)) {
            $path = substr($path, 0, -strlen($file));

            if (preg_match('/(.*)\.([\w]+)$/', $file, $match)) {
                $this->info['file'] = rawurldecode($match[1]);
                $this->info['extension'] = $match[2];
            } else {
                $this->info['file'] = rawurldecode($file);
            }
        }

        $this->info['path'] = [];

        foreach (explode('/', $path) as $dir) {
            $dir = rawurldecode($dir);

            if ($dir !== '') {
                $this->info['path'][] = $dir;
            }
        }
    }
1353036
public function create($path, $expire = 0, $fullUrl = '')
    {
        $Path_b64 = base64_encode($path);
        $expire   = $expire ?: (time() + (60 * 60 * 24)); // If expire is not defined, default is 24h
        $result     = $this->callService('POST', self::API_SHARE_LINK, [
            'path'    => $Path_b64,
            'expire'  => $expire,
            'fullurl' => $fullUrl,
        ]);

        return $result->getModel(models\FileSystem\ShareLink::class);
    }
1289465
public function copyTo(string $fullPath) : IFile
    {
        if ($this->copyCallback) {
            return call_user_func($this->copyCallback, $fullPath);
        }

        return $this->file;
    }
480434
public function readFolder( $path, $extensions = array() )
	{
		$files			= array();
		$numberCodes	= 0;
		$numberDocs		= 0;
		$numberFiles	= 0;
		$numberLength	= 0;
		$numberLines	= 0;
		$numberStrips	= 0;

		$path	= preg_replace( "@^(.+)/?$@", "\\1/", $path );

		$st		= new Alg_Time_Clock();
		$lister	= new FS_Folder_RecursiveLister( $path );
		$lister->setExtensions( $extensions );
		$list	= $lister->getList();
		foreach( $list as $entry )
		{
			$fileName	= str_replace( "\\", "/", $entry->getFilename() );
			$pathName	= str_replace( "\\", "/", $entry->getPathname() );
			
			if( substr( $fileName, 0, 1 ) == "_" )
				continue;
			if( preg_match( "@/_@", $pathName ) )
				continue;

			$countData	= FS_File_CodeLineCounter::countLines( $pathName );
			
			unset( $countData['linesCodes'] );
			unset( $countData['linesDocs'] );
			unset( $countData['linesStrips'] );

			$numberLength		+= $countData['length'];
			$numberLines		+= $countData['linesTotal'];
			
			$numberFiles		++;
			$numberStrips		+= $countData['numberStrips'];
			$numberCodes		+= $countData['numberCodes'];
			$numberDocs			+= $countData['numberDocs'];
			$files[$pathName]	= $countData;
		}
		$linesPerFile	= $numberLines / $numberFiles;
		$this->data	= array(
			'number'	=> array(
				'files'		=> $numberFiles,
				'lines'		=> $numberLines,
				'codes'		=> $numberCodes,
				'docs'		=> $numberDocs,
				'strips'	=> $numberStrips,
				'length'	=> $numberLength,
			),
			'ratio'			=> array(
				'linesPerFile'		=> round( $linesPerFile, 0 ),
				'codesPerFile'		=> round( $numberCodes / $numberFiles, 0 ),
				'docsPerFile'		=> round( $numberDocs / $numberFiles, 0 ),
				'stripsPerFile'		=> round( $numberStrips / $numberFiles, 0 ),
				'codesPerFile%'		=> round( $numberCodes / $numberFiles / $linesPerFile * 100, 1 ),
				'docsPerFile%'		=> round( $numberDocs / $numberFiles / $linesPerFile * 100, 1 ),
				'stripsPerFile%'	=> round( $numberStrips / $numberFiles / $linesPerFile * 100, 1 ),
			), 
			'files'		=> $files,
			'seconds'	=> $st->stop( 6 ),
			'path'		=> $path,
		);
	}
1050596
public static function mkdir($full, $fsencoding = '') {
        $full = self::conv_to($full, $fsencoding);
        if (!file_exists($full)) {
            return \mkdir($full, 0777, true);
        }
        return true;
    }