How to make an NSString path (file name) safe

后端 未结 7 718
陌清茗
陌清茗 2021-02-01 01:52

I\'m using very tricky fighting methods :) to make a string like Fi?le*/ Name safe for using as a file name like File_Name. I\'m sure there is a cocoa

相关标签:
7条回答
  • 2021-02-01 02:12

    This will remove all invalid characters anywhere in the filename based on Ismail's invalid character set (I have not verified how complete his set is).

    - (NSString *)_sanitizeFileNameString:(NSString *)fileName {
        NSCharacterSet* illegalFileNameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"/\\?%*|\"<>"];
        return [[fileName componentsSeparatedByCharactersInSet:illegalFileNameCharacters] componentsJoinedByString:@""];
    }
    

    Credit goes to Peter N Lewis for the idea to use componentsSeparatedByCharactersInSet:
    NSString - Convert to pure alphabet only (i.e. remove accents+punctuation)

    0 讨论(0)
  • 2021-02-01 02:13

    I iterated on johnboiles's answer, converting to Swift, and writing it as an extension:

    extension String {
        var stringForFilePath: String {
            // characterSet contains all illegal characters on OS X and Windows
            let characterSet = NSCharacterSet(charactersInString: "\"\\/?<>:*|")
            // replace "-" with character of choice
            return componentsSeparatedByCharactersInSet(characterSet).joinWithSeparator("-")
        }
    }
    

    Illegal character set referenced from here.

    0 讨论(0)
  • 2021-02-01 02:18

    Unless you're explicitly running the shell or implicitly running the shell by using a function such as popen or system, there's no reason to escape anything but the pathname separator.

    You may also want to enforce that the filename does not begin with a full stop (which would cause Finder to hide the file) and probably should also enforce that it is not empty and is fewer than NAME_MAX characters* long.

    *syslimits.h says bytes, but if you go through File Manager, it's characters. I'm not sure which is right for Cocoa.

    0 讨论(0)
  • 2021-02-01 02:23

    Solution in Swift 4

    extension String {
        var sanitizedFileName: String {
            return components(separatedBy: .init(charactersIn: "/\:\?%*|\"<>")).joined()
        }
    }
    

    Usage:

    "https://myurl.com".sanitizedFileName // = httpsmyurl.com
    
    0 讨论(0)
  • 2021-02-01 02:23
    NSURL *fileURL = [NSURL fileURLWithPath:yourFilePath isDirectory:NO];
    
    if (fileURL) {
    
        NSError *error;
    
        fileURL = [NSURL URLByResolvingAliasFileAtURL:fileURL options:(NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithoutMounting) error:&error];
    
    }
    

    Before Transfer:

    /Users/XXX/Desktop/~!@#$%^&*()_+`-={}|"<>?[]\;',.: {}<>:^ .png

    After Transfer:

    file:///Users/johnny/Desktop/~!@%23$%25%5E&*()_+%60-=%7B%7D%7C%22%3C%3E%3F%5B%5D%5C%3B',.:%20%20%7B%7D%3C%3E%5C:%5E%20.png

    0 讨论(0)
  • 2021-02-01 02:28

    According to wikipedia, the most common characters that should be excluded from filenames are:

    /\?%*|"<>

    http://en.wikipedia.org/wiki/Filename

    Given that, and since the invertedSet operation in the alternate solution can be intensive, to me the below is a cleaner approach:

    NSCharacterSet *invalidFsChars = [NSCharacterSet characterSetWithCharactersInString:@"/\\?%*|\"<>"];
    NSString *scrubbed = [originalStr stringByTrimmingCharactersInSet:invalidFsChars];
    

    This way you can still allow filenames that have dash, etc.

    0 讨论(0)
提交回复
热议问题