1

I have done research but my app downloads mp3 files every once in a while I get weird filename which doesn't hurt until I try to burn them to CD. Below is a good example. The Animals - House of the Rising Sun (1964) + clip compilation ♫♥ 50 YEARS - counting.mp3 I have some code to try and catch illegal characters but it doesn't stop this filename. Is there a better way to catch the weird stuff the code I use currently is:

 public static string RemoveIllegalFileNameChars(string input, string replacement = "")
    {
        if (input.Contains("?"))
        {
            input = input.Replace('?', char.Parse(" "));
        }
        if (input.Contains("&"))
        {
            input = input.Replace('&', char.Parse("-"));
        }
        var regexSearch = new string(Path.GetInvalidFileNameChars()) + 
                          new string(Path.GetInvalidPathChars());
        var r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));

        return r.Replace(input, replacement);
    }
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
user2180706
  • 307
  • 3
  • 8
  • 2
    Since the name you've posted is completely valid you should figure out what CD burner tool is expecting and filter everything out. There is nothing wrong with your code (at first glance) but it looks like your burner software is pickier. – Alexei Levenkov Feb 13 '19 at 03:47
  • 1
    That filename contains only legal characters, as far as your filesystem is concerned, because otherwise it could not exist with that name. So, `Path.GetInvalidFileNameChars()` won't help you here. Perhaps your CD burning software only supports ASCII characters. – Lance U. Matthews Feb 13 '19 at 03:49
  • Thanks I am using the media burner from code project https://www.codeproject.com/articles/24544/burning-and-erasing-cd-dvd-blu-ray-media-with-c-an – user2180706 Feb 13 '19 at 03:51
  • By the way, are you burning these files as an audio disc or a data disc? If the latter and this software passes through the original filename to the CD's filesystem, then you're at the mercy of whatever characters and filename lengths _that_ filesystem supports. – Lance U. Matthews Feb 13 '19 at 03:53
  • 1
    Seems like the question is just how to convert to ascii then? https://stackoverflow.com/a/30781526/9638646 – MarkReedZ Feb 13 '19 at 03:59

4 Answers4

4

The CD file system is different to the OS file system, so those Path.GetInvalidX functions don't really apply to CDs.

I'm not sure, but possibly the standard you are looking at is ISO 9660 https://en.wikipedia.org/wiki/ISO_9660 Which has an extremely limited character set in filenames.

I think that Joliet extension to that standard must be in play: https://en.wikipedia.org/wiki/Joliet_(file_system) I think that maybe you are running into the filename length problem more than anything: "The specification only allows filenames to be up to 64 Unicode characters in length". Your filename is 90 characters long.

AaronHolland
  • 1,595
  • 1
  • 16
  • 32
  • I figured it out I think your original sout code would have worked I just forgot to call it; This is what I ended up with I added this to the end of my code from above // check for non asccii characters byte[] bytes = Encoding.ASCII.GetBytes(input); char[] chars = Encoding.ASCII.GetChars(bytes); string line = new String(chars); line = line.Replace("?", ""); MessageBox.Show(line); return r.Replace(line, replacement); – user2180706 Feb 13 '19 at 04:35
  • One last question how do I use code tags in my comments? – user2180706 Feb 13 '19 at 04:36
2

The following code will turn non-ascii characters into '?'

string sOut = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(s))

Then you can use a sOut.Replace('?', '') call to take them out. Does this seem like it would work for you?

Reese Krome
  • 173
  • 6
  • I added your code to the beginning of mine and changed out the rest of the input strings to out put the problem is it doesn't allow a empty string litteral and creates an error string sOut = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(input)); sOut.Replace('?', ''); – user2180706 Feb 13 '19 at 04:07
  • I did a Char.parse(" ") it didn't work still get the following error System.ArgumentException: 'Win32 handle that was passed to Icon is not valid or is the wrong type.' – user2180706 Feb 13 '19 at 04:12
1

Although, in this case your file name is valid, to catch invalid file names, it is suggested to use GetInvalidFileNameChars() method.

 string fileName = "The Animals - House of the Rising Sun ? (1964) + clip compilation ♫♥ 50 YEARS - counting.mp3";

 byte[] bytes = Encoding.ASCII.GetBytes(fileName);
 char[] characters = Encoding.ASCII.GetChars(bytes);

 string name = new string(characters);
 StringBuilder fileN = new StringBuilder(name);
 foreach (char c in Path.GetInvalidFileNameChars())
 {
     fileN.Replace(c, '_');
 }
 string validFileName = fileN.ToString();

https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getinvalidfilenamechars?view=netframework-4.7.2

Gauravsa
  • 6,330
  • 2
  • 21
  • 30
0

Thanks for all your help the final working code is listed below

 public static string RemoveIllegalFileNameChars(string input, string replacement = "")
    {
        if (input.Contains("?"))
        {
            input = input.Replace('?', char.Parse(" "));
        }
        if (input.Contains("&"))
        {
            input = input.Replace('&', char.Parse("-"));
        }
        var regexSearch = new string(Path.GetInvalidFileNameChars()) + new     string(Path.GetInvalidPathChars());
        var r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));

        // check for non asccii characters
        byte[] bytes = Encoding.ASCII.GetBytes(input);
        char[] chars = Encoding.ASCII.GetChars(bytes);
        string line = new String(chars);
        line = line.Replace("?", "");
        //MessageBox.Show(line);
        return r.Replace(line, replacement);
    }
user2180706
  • 307
  • 3
  • 8