在 C# 中使用通配符查找文件
Find files using wild card in C#
我正在尝试从目录中查找文件:
String[] search1 = Directory.GetFiles(voiceSource, "85267-*.wav")
.Select(path => Path.GetFileName(path))
.ToArray();
String[] search2 = Directory.GetFiles(voiceSource, "85267 *.wav")
.Select(path => Path.GetFileName(path))
.ToArray();
但在 search1
中,它同时选择了 85267-s.wav
和 85267 -s.wav
。但我只想选择 85267-s.wav
。
search2
表现不错。
我该怎么做?
是的,这是 MS-Dos 8.3 短名称支持的副作用,目前在大多数文件系统上仍处于打开状态。您可以使用 DIR /X 命令看到的东西,它显示那些短名称。在我的机器上:
C:\temp>dir /x *.wav
01/21/2015 09:11 AM 6 85267-~1.WAV 85267 -s.wav
01/21/2015 09:11 AM 6 85267-s.wav
2 File(s) 12 bytes
0 Dir(s) 235,121,160,192 bytes free
请注意“85267 -s”的简称是如何缺少 space 的。它不是短名称中的有效字符。现在剩下的也符合你的通配符。
那些短名称的麻烦还不止于此,像 *.wav
这样的通配符也会匹配像 foobar.wavx
这样完全不同的文件类型的文件。
坦率地说,短名称生成是上个世纪的遗留物,今天应该关闭。但这通常不是您可以控制的。您必须处理这些意外匹配并仔细检查您返回的内容。以正则表达式为例。
您遇到的问题是由于短文件名。由于 85267 -s.wav
会得到 85267-~1.WAV
并且因为它与通配符 "85267-*.wav"
匹配,所以您可以取回两个文件。
在Directory.GetFiles Method (String, String)
中有解释
Because this method checks against file names with both the 8.3 file
name format and the long file name format, a search pattern similar
to "1.txt" may return unexpected file names. For example, using a
search pattern of "1.txt" will return "longfilename.txt" because the
equivalent 8.3 file name format would be "longf~1.txt".
对于解决方法,您可以使用 Directory.EnumerateFiles
首先 select 两个符合您条件的文件,然后比较 实际(长) 文件名部分使用 StartsWith
。请记住 EnumerateFiles
进行惰性评估。
String[] search1 = Directory.EnumerateFiles(@"C:\test", "85267-*.wav")
.Where(file => Path.GetFileName(file).StartsWith("85267-"))
.Select(path => Path.GetFileName(path))
.ToArray();
我正在尝试从目录中查找文件:
String[] search1 = Directory.GetFiles(voiceSource, "85267-*.wav")
.Select(path => Path.GetFileName(path))
.ToArray();
String[] search2 = Directory.GetFiles(voiceSource, "85267 *.wav")
.Select(path => Path.GetFileName(path))
.ToArray();
但在 search1
中,它同时选择了 85267-s.wav
和 85267 -s.wav
。但我只想选择 85267-s.wav
。
search2
表现不错。
我该怎么做?
是的,这是 MS-Dos 8.3 短名称支持的副作用,目前在大多数文件系统上仍处于打开状态。您可以使用 DIR /X 命令看到的东西,它显示那些短名称。在我的机器上:
C:\temp>dir /x *.wav
01/21/2015 09:11 AM 6 85267-~1.WAV 85267 -s.wav
01/21/2015 09:11 AM 6 85267-s.wav
2 File(s) 12 bytes
0 Dir(s) 235,121,160,192 bytes free
请注意“85267 -s”的简称是如何缺少 space 的。它不是短名称中的有效字符。现在剩下的也符合你的通配符。
那些短名称的麻烦还不止于此,像 *.wav
这样的通配符也会匹配像 foobar.wavx
这样完全不同的文件类型的文件。
坦率地说,短名称生成是上个世纪的遗留物,今天应该关闭。但这通常不是您可以控制的。您必须处理这些意外匹配并仔细检查您返回的内容。以正则表达式为例。
您遇到的问题是由于短文件名。由于 85267 -s.wav
会得到 85267-~1.WAV
并且因为它与通配符 "85267-*.wav"
匹配,所以您可以取回两个文件。
在Directory.GetFiles Method (String, String)
中有解释Because this method checks against file names with both the 8.3 file name format and the long file name format, a search pattern similar to "1.txt" may return unexpected file names. For example, using a search pattern of "1.txt" will return "longfilename.txt" because the equivalent 8.3 file name format would be "longf~1.txt".
对于解决方法,您可以使用 Directory.EnumerateFiles
首先 select 两个符合您条件的文件,然后比较 实际(长) 文件名部分使用 StartsWith
。请记住 EnumerateFiles
进行惰性评估。
String[] search1 = Directory.EnumerateFiles(@"C:\test", "85267-*.wav")
.Where(file => Path.GetFileName(file).StartsWith("85267-"))
.Select(path => Path.GetFileName(path))
.ToArray();