我有一个函数可以检测由字符串启动的所有文件,并返回一个填充了相应文件的数组,但它开始变慢,因为我在特定目录中有20000个文件。 我需要优化这个功能,但我只是看不出来。这是功能:
function DetectPrefix ($filePath, $prefix)
{
$dh = opendir($filePath);
while (false !== ($filename = readdir($dh)))
{
$posIni = strpos( $filename, $prefix);
if ($posIni===0):
$files[] = $filename;
endif;
}
if (count($files)>0){
return $files;
} else {
return null;
}
}
我还能做些什么?
由于
答案 0 :(得分:11)
$files = glob('/file/path/prefix*');
维基百科按其文件名的前几个字母打破上传内容,因此excelfile.xls
将放在/uploads/e/x
这样的目录中,而textfile.txt
将放入/uploads/t/e
。
这不仅减少了glob
(或任何其他方法)必须排序的文件数量,而且还避免了其他人提到的目录问题中的最大文件。
答案 1 :(得分:4)
您可以使用scandir()列出目录中的文件,而不是使用readdir()
逐个迭代它们。 scandir()返回文件数组。
但是,如果您可以更改文件系统组织会更好 - 您真的需要在一个目录中存储20000多个文件吗?
答案 2 :(得分:2)
正如其他答案所提到的,我会查看glob(),scandir()和/或DirectoryIterator类,不需要重新创建轮子。
但请注意!检查您的操作系统,但单个目录中的最大文件数可能有限制。如果是这种情况,您只是继续在同一目录中添加文件,那么您将遇到一些停机时间,以及一些问题,当你达到极限。此错误可能会显示为权限或写入失败,而不是明显的“您无法在单个目录中写入更多文件”消息。
答案 3 :(得分:1)
我不确定,但DirectoryIterator可能要快一点。还要添加缓存,以便仅在添加或删除文件时生成列表。
答案 4 :(得分:0)
您只需要比较前缀字符的第一个长度。所以试试这个:
function DetectPrefix($filePath, $prefix) {
$dh = opendir($filePath);
$len = strlen($prefix);
$files = array();
while (false !== ($filename = readdir($dh))) {
if (substr($filename, 0, $len) === $prefix) {
$files[] = $filename;
}
}
if (count($files)) {
return $files;
} else {
return null;
}
}