The following snippet of code has been working fine for weeks but today I got this exception:
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)
...
Here is the code
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
};
}
I thought, OK, the deviceId bit must be junk but looking in the log output I got:
Definition for '3912'
I think that the line of code that would be throwing that exception is the following but I do not have PDBs so I am not 100% sure hence posting the entire function.
var files = info.GetFiles(deviceId + "_????.txt");
I checked the Path.GetInvalidPathChars MSDN page to see what invalid characters are and I think that passing "3912_????.txt"
into that function should be fine.
I figure the directory must be fine or that whole .Exists
thing would have fallen over.
So do any of the great StackOverfloweions know what could possibly have made this happen (I just restarted my application and have not seen it happen again yet...)?
Update
Doing a dir in that directory I have the following:
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
The most likely reason is that deviceId
contains an invalid character.
For example, a trailing null character ("\0") would give this result, and would probably not show up in your log.
You could check for this by tracing the values of each character in your deviceId string - e.g.:
Console.WriteLine("Device Id {0} ({1})",
deviceId,
String.Join("-", deviceId.Select(x => ((int)x).ToString("X2")).ToArray()));
Looking at the stack trace, it seems to be cycling through the matching files in the given directory, and then trying to obtain a full path using Path.InternalCombine()
. That checks the for invalid characters, which throws the exception.
Since invalid characters in your storePath
variable should have thrown an exception in the DirectoryInfo
constructor, I see only one ways that an invalid character could creep in:
One of the file names in the directory contains an illegal character.
Sounds silly, but stranger things have happened... You can check if that is the cause by getting a file listing from that directory, preferably by running the dir
command on the command line, and piping the result into a text file.
Edit:
Just saw that you already did - and it seems I was wrong. In that case I concur with Joe, the only remaining suspect is the deviceId
. See if you can log a hex representation of the string, as shown here, that should also show \0
and any other special characters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With