以下几段代码一直运行良好数周,但今天我遇到了这个例外:
System.ArgumentException: Illegal characters in path.
at System.IO.Path.CheckInvalidPathChars(String path)
at System.IO.Path.InternalCombine(String path1, String path2)
at System.IO.FileSystemEnumerableIterator`1.GetFullSearchString(String fullPath, String searchPattern)
at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler)
at System.IO.DirectoryInfo.InternalGetFiles(String searchPattern, SearchOption searchOption)
at System.IO.DirectoryInfo.GetFiles(String searchPattern)
at MyCompany.GetSendDefinition(String deviceId)
...
这是代码
public SendDefinition GetSendDefinition(string deviceId)
{
Logger.Debug("Definition for '{0}'" deviceId);
string storePath = Path.Combine(_serviceFolder, TcpFolder);
var info = new DirectoryInfo(storePath);
if (!info.Exists)
{
return null;
}
var files = info.GetFiles(deviceId + "_????.txt");
int numberOfMessage = files.Length;
var file = files.OrderBy(x => x.CreationTime).FirstOrDefault();
if (file == null)
{
return new SendDefinition
{
Message = string.Empty,
NumberOfMessages = 0
};
}
string response;
using (var reader = new StreamReader(file.FullName))
{
response = reader.ReadToEnd().Replace("\r\n", "");
}
string[] data = file.Name.Split('.');
var name = data[0].Split('_');
if (name.Length > 3)
{
var count = Convert.ToInt16(name[3],
CultureInfo.InvariantCulture);
if (count < 5)
{
count++;
string newFileName = Path
.Combine(storePath,
data[0].Substring(0, data[0].Length - 1)
+ count + ".txt");
file.CopyTo(newFileName, true);
}
file.Delete();
}
else
{
string newFileName = Path.Combine(storePath,
data[0] + "_0.txt");
file.CopyTo(newFileName, true);
file.Delete();
}
return new SendDefinition
{
Message = response,
NumberOfMessages = numberOfMessage
};
}
我想,好吧,deviceId位必须是垃圾,但查看我得到的日志输出:
Definition for '3912'
我认为抛出该异常的代码行如下,但我没有PDB,所以我不是100%肯定因此发布了整个函数。
var files = info.GetFiles(deviceId + "_????.txt");
我检查了Path.GetInvalidPathChars MSDN页面以查看哪些无效字符,我认为将"3912_????.txt"
传递给该函数应该没问题。
我认为目录必须正常,否则整个.Exists
事情就会崩溃。
所有伟大的StackOverfloweions都知道可能会发生什么事情(我刚刚重新启动我的应用程序并且还没有看到它再次发生......)?
更新
在该目录中执行dir我有以下内容:
14.03.2012 16:03 <DIR> .
14.03.2012 16:03 <DIR> ..
09.03.2012 13:51 101 3055_P_275112090312.txt
25.01.2012 10:52 99 3055_X_325209250112.txt
10.02.2012 08:38 74 3055_Z_373807100212.txt
3 Datei(en) 274 Bytes
2 Verzeichnis(se), 33.613.897.728 Bytes frei
答案 0 :(得分:2)
最可能的原因是deviceId
包含无效字符。
例如,尾随空字符(“\ 0”)会给出此结果,并且可能不会显示在您的日志中。
您可以通过跟踪deviceId字符串中每个字符的值来检查这一点 - 例如:
Console.WriteLine("Device Id {0} ({1})",
deviceId,
String.Join("-", deviceId.Select(x => ((int)x).ToString("X2")).ToArray()));
答案 1 :(得分:1)
查看堆栈跟踪,它似乎循环遍历给定目录中的匹配文件,然后尝试使用Path.InternalCombine()
获取完整路径。检查无效字符,这会抛出异常。
由于storePath
变量中的无效字符应该在DirectoryInfo
构造函数中抛出异常,因此我只看到一种无效字符可能出现的方式:
目录中的一个文件名包含非法字符。
听起来很傻,但发生了奇怪的事情......您可以通过从该目录获取文件列表来检查是否是原因,最好是在命令行上运行dir
命令,然后管道化结果进入文本文件。
修改强>
刚刚看到你已经做过 - 而且看起来我错了。在这种情况下,我同意Joe,唯一剩下的嫌疑人是deviceId
。看看是否可以记录字符串的十六进制表示,如here所示,它还应显示\0
和任何其他特殊字符。
答案 2 :(得分:0)
当我在mac上扫描目录时(通过网络共享),我遇到了这个问题。
DirectoryInfo.GetFiles(@ “//的MacBook / sharedfolder”)
似乎在Mac上使用像&lt;,&gt;这样的字符是非常合法的?在文件名中,但在Windows上它不是。
当目录中的某个文件名包含无效字符时,我收到此“非法字符”错误。
答案 3 :(得分:0)
当我尝试打电话时,我遇到了这个例外
new DirectoryInfo(folderPath).GetFiles("x??\\*.dll")
据我所知,GetFiles()
不支持使用通配符作为目录名。所以相反,我使用了这个有用的声明:
new DirectoryInfo(folderPath).GetDirectories("x??").SelectMany(d => d.GetFiles("*.dll"))
答案 4 :(得分:0)
我正在尝试获取所有与基本文件名匹配的文件,然后在文件扩展名之前加上下划线和任何内容。我这样做时会遇到同样的错误。
DirectoryInfo di = new DirectoryInfo(txtAlternateImagesFolder.Text);
string matchPattern = imageFileName.Replace(".jpg", "_*.jpg");
var alternates = di.GetFiles(@matchPattern);
然后我尝试了这个:
string matchPattern = imageFileName.Replace(".jpg", "");
var alternates = di.GetFiles(matchPattern).Where(f => f.Name.Contains(matchPattern) && f.Name!=imageFileName);
我没有收到错误,但我也没有收到匹配的文件。我需要导致异常的通配符“*”。所以我的下一次尝试是:
DirectoryInfo di = new DirectoryInfo($@" {txtAlternateImagesFolder.Text}");
var images = di.GetFiles("*.jpg");
//Skipping some use feedback code
string matchPattern = imageFileName.Replace(".jpg", "*.jpg");
var matches = images.Where(f => f.Name.Contains(matchPattern) && f.Name != imageFileName);
我的理论是,如果我通常在GetFiles()方法中使用通配符而不是在Where()谓词中使用通配符,那么它可能不会爆炸。好理论,但没有快乐。我最后不得不通过将带有通配符的匹配定义为“包含没有扩展名的文件名,但与文件名不同。”
答案 5 :(得分:-1)
你不能拥有?在文件名中。 \ / : * ? " < > |
不是文件名的有效字符。
编辑: CheckInvalidPathChars正在寻找以下字符:
num == 34 || num == 60 || num == 62 || num == 124 || num&lt; 32
为什么不在代码中实现它并抛出/处理自己的异常。