gpt4 book ai didi

php - 从 RecursiveDirectoryIterator 过滤目录

转载 作者:搜寻专家 更新时间:2023-11-01 08:41:21 27 4
gpt4 key购买 nike

因此,在我学习 Java 编程书籍的过程中,为了进一步了解 Android 开发,我遇到了 JSONObject 和 JSONArray。经过一些研究后,我整理了一个 php 脚本来读取目标目录的内容,输出是一个 JSON 文件,其中包含足够的信息以使用我的学习 Material 中涉及的 Java 类进行解析。

唯一的问题是,自从我接触 php 以来已经有好几年了,我从几个来源收集的信息是我唯一能理解的信息——情况是这样的:

如何从我的结果中过滤掉(在将它们添加到我的 JSON 文件之前)一组排除项(文件和/或目录),例如:“@eaDir”、“Thumbs.db”、“.DS_File”等

这里是有问题的代码:

#!/usr/bin/php
<?php

/* Run with: php [filename].php /path/to/folder/
Outputs file_list.json in target folder */

// Where are we running on?
if (PHP_SAPI === 'cli') {
$argument1 = $argv[1];
$argument2 = $argv[2];
}
else {
$argument1 = $_GET['argument1'];
$argument2 = $_GET['argument2'];
}

// Set output dir and file
$out = $argument1 . '/file_list.json';

/*
* @param Array $types
* @abstract Array of allowed file types
*/
$types = Array ('mp3', 'ogg');

if (!isset($argv[1]))
exit("Must specify a directory to scan\n");

if (!is_dir($argv[1]))
exit($argv[1]."' is not a directory\n");

/*
* @name getList
* @param Array $dir
* @param Array $types
* @abstract Recursively iterates over specified directory
* populating array based on array of file extensions
* @return Array $files
*/
function getList($dir, $types) {
$it = new RecursiveDirectoryIterator($dir);
foreach(new RecursiveIteratorIterator($it) as $file) {
if (in_array(strtolower(array_pop(explode('.', $file))), $types)) {
$files[] = $file->__toString();
}
}
return $files;
}

/*
* @name getDetails
* @param Array $dir
* @param Array $types
* @abstract Recursively iterates over specified directory
* populating array with details of each file
* @return Array $files
*/
function getDetails($types, $array)
{
foreach($types as $type)
{
foreach($array as $file)
{
if (strcasecmp($type, array_pop(explode('.', $file))) == 0) {
$files[$type][basename($file)];
$files[$type][basename($file)]['source'] = $file;
$files[$type][basename($file)]['size'] = filesize($file);
}
}
}
return array('files'=>$files);
}

if (!function_exists('json_encode')) {

/*
* @name json_encode
* @param Mixed $val
* @abstract Alternate emulated json_encode function
* @return Object $res
*/
function json_encode($val)
{
if (is_string($val)) return '"'.addslashes($val).'"';
if (is_numeric($val)) return $val;
if ($val === null) return 'null';
if ($val === true) return 'true';
if ($val === false) return 'false';

$assoc = false;
$i = 0;
foreach ($val as $k=>$v){
if ($k !== $i++){
$assoc = true;
break;
}
}
$res = array();
foreach ($val as $k=>$v){
$v = json_encode($v);
if ($assoc){
$k = '"'.addslashes($k).'"';
$v = $k.':'.$v;
}
$res[] = $v;
}
$res = implode(',', $res);
return ($assoc)? '{'.$res.'}' : '['.$res.']';
}
}

/* Open file in write mode */
$fp = fopen($out, 'w');

/* Run application & save file */
fwrite($fp, json_encode(getDetails($types, getList($argv[1], $types))));

/* Close file */
fclose($fp);

exit();

我在 Synology DS1513+ 上运行它,它总是吐出名为 @eaDir 的目录。这是我禁用但在下一次更新时返回的索引过程(有时在重新启动后)。我想添加更多文件类型,而不必担心脚本会检查我上面提到的目录。

我怎样才能做到这一点?

编辑:经过更多的阅读和研究,我添加了一个嵌套的 if 条件来过滤目录,这是包含更改的代码:

#!/usr/bin/php
<?php

/* Run with: php [filename].php /path/to/folder/
Outputs file_list.json in target folder */

// Where are we running on?
if (PHP_SAPI === 'cli') {
$argument1 = $argv[1];
$argument2 = $argv[2];
} else {
$argument1 = $_GET['argument1'];
$argument2 = $_GET['argument2'];
}

// Set output dir and file
$out = $argument1 . '/file_list.json';

/*
* @param Array $types
* @abstract Array of allowed file types
*/
$types = ['mp3', 'ogg', 'jpg'];
$ignoreDir = ['@eaDir'];

if (!isset($argv[1])) {
exit("Must specify a directory to scan\n");
}

if (!is_dir($argv[1])) {
exit($argv[1] . "' is not a directory\n");
}

/*
* @name getList
* @param Array $dir
* @param Array $types
* @param Array $ignoreDir
* @abstract Recursively iterates over specified directory
* populating array based on array of file extensions
* while ignoring directories specified in ignoreDir
* @return Array $files
*/

function getList($dir, $types, $ignoreDir) {
$it = new RecursiveDirectoryIterator($dir);
foreach (new RecursiveIteratorIterator($it) as $file) {
if (in_array(strtolower(array_pop(explode('.', $file))), $types)) {
if (!in_array($it, $ignoreDir)) {
$files[] = $file->__toString();
}
}
}
return $files;
}

/*
* @name getDetails
* @param Array $dir
* @param Array $types
* @abstract Recursively iterates over specified directory
* populating array with details of each file
* @return Array $files
*/

function getDetails($types, $array) {
foreach ($types as $type) {
foreach ($array as $file) {
if (strcasecmp($type, array_pop(explode('.', $file))) == 0) {
$files[$type][basename($file)]['name'] = basename($file);
$files[$type][basename($file)]['size'] = filesize($file);
$files[$type][basename($file)]['source'] = $file;
$files[$type][basename($file)]['date'] = date ("F d Y H:i:s", filemtime($file));
}
}
}
return array('files' => $files);
}

if (!function_exists('json_encode')) {

/*
* @name json_encode
* @param Mixed $val
* @abstract Alternate emulated json_encode function
* @return Object $res
*/
function json_encode($val)
{
if (is_string($val)) return '"'.addslashes($val).'"';
if (is_numeric($val)) return $val;
if ($val === null) return 'null';
if ($val === true) return 'true';
if ($val === false) return 'false';

$assoc = false;
$i = 0;
foreach ($val as $k=>$v){
if ($k !== $i++){
$assoc = true;
break;
}
}
$res = array();
foreach ($val as $k=>$v){
$v = json_encode($v);
if ($assoc){
$k = '"'.addslashes($k).'"';
$v = $k.':'.$v;
}
$res[] = $v;
}
$res = implode(',', $res);
return ($assoc)? '{'.$res.'}' : '['.$res.']';
}
}

/* Open file in write mode */
$fp = fopen($out, 'w');

/* Run application & save file */
fwrite($fp, json_encode(getDetails($types, getList($argv[1], $types, $ignoreDir)), JSON_PRETTY_PRINT));

/* Close file */
fclose($fp);

exit();

我仍然有兴趣了解更多关于 RecursiveDirectoryIterator 如何使用过滤器的信息,但到目前为止这已经可以满足我的需求了。

最佳答案

PHP 有一个类似的类 RecursiveCallbackFilterIterator

http://php.net/manual/en/class.recursivecallbackfilteriterator.php

如果您使用它而不是当前的递归迭代器,它将让您在迭代每个文件/目录之前“预过滤”。

您可以根据需要进行过滤,包括目录、文件名、文件大小等。

然后您可以像这样排除目录:

$dir = new RecursiveDirectoryIterator('dirYouWantToIterateOver');

//define the directories you don't want to include
$excludeDirs = array('@eaDir', 'notThisDir', 'notInThisOtherDir');

$files = new RecursiveCallbackFilterIterator($dir, function($file, $key, $iterator) use ($excludeDirs){
if($iterator->hasChildren() && !in_array($file->getFilename(), $excludeDirs)){
return true;
}
return $file->isFile();
});

foreach(new RecursiveIteratorIterator($files) as $file){
//do something with each file
echo($file->getPathname() . PHP_EOL);
}

关于php - 从 RecursiveDirectoryIterator 过滤目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32296838/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com