请注意,我是在您打算使用directory
参数代替rootDir
类级变量的假设下进行操作的。
您在这里有两个选择。
hacky,但更有效的方法
在这种情况下,您传递列表对象。我将使用List<string>
而不是ArrayList
.
public List<string> getMusicFiles(string directory) {
var list = new List<string>();
getMusicFiles(list, directory);
return list;
}
private void getMusicFilesInternal(List<string> songpaths, string directory)
{
string[] localFiles= System.IO.Directory.GetFiles(directory);
for(int i=0; i<localFiles.Length-1; i++) {
if(isMusicFile(localFiles[i])) {
songpaths.add(localFiles[i]);
}
}
string[] localFolders= System.IO.Directory.GetDirectories(directory);
for(int i=0; i<localFolder.Length-1; i++) {
getMusicFiles(songpaths, localFolder[i]);
}
}
效率较低但实用的方式
每次递归时返回列表并聚合结果:
public IList<string> getMusicFiles(string directory)
{
List<string> songpaths = new List<string>();
string[] localFiles= System.IO.Directory.GetFiles(directory);
for(int i=0; i<localFiles.Length-1; i++) {
if(isMusicFile(localFiles[i])) {
songpaths.add(localFiles[i]);
}
}
string[] localFolders= System.IO.Directory.GetDirectories(directory);
for(int i=0; i<localFolder.Length-1; i++) {
songpaths.AddRange(getMusicFiles(localFolder[i]));
}
return songpaths;
}
您也可以使用延迟执行来实现这一点,这仍然不如第一个示例高效,但在使用结果时为您提供了更大的灵活性:
public IEnumerable<string> getMusicFiles(string directory)
{
string[] localFiles= System.IO.Directory.GetFiles(directory);
for(int i=0; i<localFiles.Length-1; i++) {
if(isMusicFile(localFiles[i])) {
yield return localFiles[i];
}
}
string[] localFolders= System.IO.Directory.GetDirectories(directory);
for(int i=0; i<localFolder.Length-1; i++) {
foreach (var j in getMusicFiles(localFolder[i])) {
yield return j;
}
}
}
这将返回一个 enumerable,每次枚举它时都会执行搜索操作,类似于 Linq 查询的工作方式。您可以调用ToList()
结果来执行查询并将结果存储在一个列表中,您可以多次枚举该列表而无需再次执行查询。
如果我清理所有代码,以下是我可能会选择使用的变体。您的原始代码有几个问题(您从数组的Length
属性中减去一个,即使这会导致您跳过最后一个元素,并且还有一些其他拼写错误)。
public IEnumerable<string> getMusicFiles(string directory)
{
foreach (var file in System.IO.Directory.GetFiles(directory)) {
if (isMusicFile(file)) {
yield return file;
}
}
foreach (var dir in System.IO.Directory.GetDirectories(directory)) {
foreach (var musicFile in getMusicFiles(dir)) {
yield return musicFile;
}
}
}
如果您担心 的性能foreach
,请不要。首先,您应该首先针对可读性进行编码,然后才是性能,只有在发现瓶颈时才进行优化。其次,当您foreach
在数组类型上使用时,编译器会将其转换为Length
基于等效的迭代,而不是通过IEnumerator<T>
.