What can cause this ArgumentException from Directory.GetFiles?

The following code snippet works fine for several 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 should be garbage, but looking at the output log, I got:

 Definition for '3912' 

I think the line of code that will throw this exception is the following, but I don't have a PDB, so I'm not 100% sure, so I'm sending the whole function.

 var files = info.GetFiles(deviceId + "_????.txt"); 

I checked the Path.GetInvalidPathChars MSDN page to find out which characters are invalid and I think that passing "3912_????.txt" to this function should be fine.

I believe the directory should be fine, or the whole .Exists thing .Exists fall.

So any of the great StackOverfloweions knows what this could do (I just restarted the application and haven't seen it again ...)?

Update

Running a directory in this directory I have:

 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 
+7
source share
6 answers

The most likely reason is that deviceId contains an invalid character.

For example, a trailing null character ("\ 0") will give this result and probably will not appear in your log.

You can verify this by checking the values ​​of each character in your deviceId string - for example:

 Console.WriteLine("Device Id {0} ({1})", deviceId, String.Join("-", deviceId.Select(x => ((int)x).ToString("X2")).ToArray())); 
+2
source

Looking at the stack trace, it seems to cycle through the appropriate files in this directory, and then try to get the full path using Path.InternalCombine() . This checks for invalid characters that throw an exception.

Since the invalid characters in your storePath variable should have thrown an exception in the DirectoryInfo constructor, I see only one way in which the invalid character could be painted over:

One of the file names in the directory contains an invalid character.

It sounds silly, but weirder things happened ... You can check if this is the reason by getting the list of files from this directory, preferably by running the dir command on the command line and laying the result in a text file.

Edit:
I just saw what you have already done - and it seems that I was wrong. In this case, I agree with Joe , the only remaining suspect is deviceId . See if you can write the hexadecimal representation of the string, as shown here , which should also include \0 and any other special characters.

+1
source

I ran into this problem when scanning a directory on a Mac (via a network share).

DirectoryInfo.GetFiles (@ "// MacBook / share_folder")

Apparently, it is completely legal on mac to have characters like <,>,? in the file name, but in windows it is not.

If one of the file names in the directory had invalid characters, I got this "illegal characters" error.

0
source

I got this exception when I tried to call
new DirectoryInfo(folderPath).GetFiles("x??\\*.dll")

So, as far as I can tell, GetFiles() does not support using a wildcard for a directory name. So instead, I used this expression that worked:
new DirectoryInfo(folderPath).GetDirectories("x??").SelectMany(d => d.GetFiles("*.dll"))

0
source

I am trying to get all the files that match the name of the base file, and then underscore and anything before the file extension. I get the same error when I do this.

  DirectoryInfo di = new DirectoryInfo(txtAlternateImagesFolder.Text); string matchPattern = imageFileName.Replace(".jpg", "_*.jpg"); var alternates = di.GetFiles(@matchPattern); 

Then I tried this instead:

 string matchPattern = imageFileName.Replace(".jpg", ""); var alternates = di.GetFiles(matchPattern).Where(f => f.Name.Contains(matchPattern) && f.Name!=imageFileName); 

I did not receive an error message, but I did not take the corresponding files either. I need a "*" pattern that throws an exception. So my next attempt:

  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); 

My theory was that if I used the template in the GetFiles () method, but not in the Where () predicate, it might not explode. Good theory, but without joy. I finally had to muscle it by specifying a wildcard match as "containing a file name without an extension, but not the same as the file name".

0
source

Can't you have it? in the file name. \ / : * ? " < > | \ / : * ? " < > | are invalid characters for the file name.

EDIT: CheckInvalidPathChars searches for the following characters:

num == 34 || num == 60 || num == 62 || num == 124 || num <32

Why not implement this in your code, as well as throw / handle your own exception.

-one
source

All Articles