Подтвердить что ты не робот

Какие символы разрешены в имени файла iOS?

Я ищу способ убедиться, что строка может использоваться как имя файла в iOS. Я сейчас в разделе кода, который удаляет несовместимые символы. Мне интересно, правильно ли я делаю это.

NSString *filename = @"A file name";
fileName = [fileName stringByTrimmingCharactersInSet: [NSCharacterSet controlCharacterSet]];
fileName = [fileName stringByTrimmingCharactersInSet: [NSCharacterSet newlineCharacterSet]];

Мне также интересно, существует ли уже метод, который проверяет строку как имя файла.

Спасибо за ваш совет!

4b9b3361

Ответ 1

Прежде всего, вы используете неправильный метод. Обрезка строки приведет только к удалению символов в начале и конце строки.

То, что вы ищете, это нечто большее:

fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"_"];

Однако, это неоптимальное решение, так как вам придется делать это для каждого символа, который вы хотите исключить, поэтому, возможно, вы хотите продолжать искать или писать, вы являетесь собственным методом для управления строкой.

iOS является основанной на UNIX и поэтому я предполагаю, что он поддерживает почти любые символы в именах файлов. UNIX разрешает пробелы, <, > , |, \,:, (,), &, а также подстановочные знаки, такие как? и *, для цитирования или экранирования с помощью символа \. Однако я бы не использовал ни одного из этих символов в моих файлах. Фактически, я бы ограничил символы в моих файлах "a" - "z", "0" - "9", "_" и ".".

Ответ 2

Используйте RegEx:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^a-zA-Z0-9_]+" options:0 error:nil];
filename = [regex stringByReplacingMatchesInString:filename options:0 range:NSMakeRange(0, filename.length) withTemplate:@"-"];

Ответ 3

Я считаю, что это чище и, вероятно, намного более производительно. Это основано на решении Ангела Найденова, но сначала создается набор символов со всеми недопустимыми символами, а затем вызывается components(separatedBy:) только один раз.

Swift 3 & 4

var invalidCharacters = CharacterSet(charactersIn: ":/")
invalidCharacters.formUnion(.newlines)
invalidCharacters.formUnion(.illegalCharacters)
invalidCharacters.formUnion(.controlCharacters)

let newFilename = originalFilename
    .components(separatedBy: invalidCharacters)
    .joined(separator: "")

Swift 2

let invalidCharacters = NSMutableCharacterSet(charactersInString: ":/")
invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.newlineCharacterSet())
invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.illegalCharacterSet())
invalidCharacters.formUnionWithCharacterSet(NSCharacterSet.controlCharacterSet())

let filename = originalFilename
    .componentsSeparatedByCharactersInSet(invalidCharacters)
    .joinWithSeparator("")

Ответ 4

Мне пришлось сохранять удаленные файлы локально с именами файлов, содержащими другие символы, кроме основных буквенно-цифровых символов. Я использую метод ниже, чтобы вычеркнуть потенциальные недопустимые символы, гарантируя ему действительное имя файла для файловой системы при создании NSURL с использованием URLWithString:

    filename = [[filename componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@"" ];
    filename = [[filename componentsSeparatedByCharactersInSet:[NSCharacterSet illegalCharacterSet]] componentsJoinedByString:@"" ];
    filename = [[filename componentsSeparatedByCharactersInSet:[NSCharacterSet symbolCharacterSet]] componentsJoinedByString:@"" ];
    fileURLString = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
    fileURL = [NSURL URLWithString:fileURLString];

Вы также можете сначала протестировать ошибки столкновений, используя:

    [[NSFileManager defaultManager] fileExistsAtPath:[fileURL absoluteString]]

Ответ 5

Поскольку я не видел список с допустимыми символами в этом вопросе, но вопрос нуждался в списке с такими символами, я добавляю немного более подробную информацию по этой теме.

Сначала нам нужно знать, что такое файловая система, которую используют устройства iOS. Используя несколько онлайн-источников, похоже, это HFSX, который является версией с учетом регистра HFS+. И включая одну ссылку здесь для справки: https://apple.stackexchange.com/questions/83671/what-filesystem-does-ios-use

Теперь, когда мы знаем, что такое файловая система, мы можем искать, какие символы недопустимы. И это похоже: двоеточие (:) и слэш (/). Вот ссылка для справки: http://www.comentum.com/File-Systems-HFS-FAT-UFS.html

Имея эту информацию и то, что другие написали в этой теме, мое личное предпочтение удаления недопустимых символов из имен файлов - это следующий код Swift:

filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()))
filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.illegalCharacterSet()))
filename = "-".join(filename.componentsSeparatedByCharactersInSet(NSCharacterSet.controlCharacterSet()))
filename = "-".join(filename.componentsSeparatedByString(":"))
filename = "-".join(filename.componentsSeparatedByString("/"))

Причина, по которой я не предпочитаю подход RegEx, заключается в том, что он кажется слишком ограничительным для меня. Я не хочу ограничивать пользователей только латинскими символами. Они могут также хотеть использовать некоторые китайцы, кириллицу или что-то еще, что им нравится.

Счастливое кодирование!

Ответ 6

Это расширение String (Swift 4.2) поможет преобразовать недопустимое имя файла iOS в правильное имя файла iOS.

 extension String {
    func convertToValidFileName() -> String {
        let invalidFileNameCharactersRegex = "[^a-zA-Z0-9_]+"
        let fullRange = startIndex..<endIndex
        let validName = replacingOccurrences(of: invalidFileNameCharactersRegex,
                                           with: "-",
                                        options: .regularExpression,
                                          range: fullRange)
        return validName
    }
}

Например,

"name.name?/[email protected]".convertToValudFileName()       // "name-name-23-1asd"

"!Hello.312,^%-0//\r\r".convertToValidFileName()        // "-Hello-312-0-"

"/foo/bar/pop?soda=yes|please".convertToValidFileName() // "-foo-bar-pop-soda-yes-please"

Ответ 7

Я придумал следующее решение. Пока работает хорошо.

import Foundation

extension String {
    func removeUnsupportedCharactersForFileName() -> String {
        var cleanString = self
        ["?", "/", "\\", "*"].forEach {
            cleanString = cleanString.replacingOccurrences(of: $0, with: "-")
        }
        return cleanString
    }
}

let a = "***???foo.png"
let validString = a.removeUnsupportedCharactersForFileName()

Ответ 8

Я очень доволен этим решением:

NSString *testString = @"This*is::/legal.😀,?縦書き 123";
NSString *result = [[[testString componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]] componentsJoinedByString:@"-"];

Вывод:

"This-is-legal-縦書き-123"

Что это за колдовство?

Позвольте мне разбить его на несколько строк, чтобы он понял, что происходит:

NSString *testString = @"This*is::/legal.😀,?縦書き 123";
// Get a character set for everything that NOT alphanumeric.
NSCharacterSet *nonAlphanumericCharacterSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
// Split the string on each non-alphanumeric character, thus removing them.
NSArray *cleanedUpComponentsWithBlanks = [testString componentsSeparatedByCharactersInSet:nonAlphanumericCharacterSet];
// Filter out empty strings ("length" is a KVO-compliant property that the predicate can call on each NSString in the array).
NSArray *cleanedUpComponentsWithoutBlanks = [cleanedUpComponentsWithBlanks filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]];
// Put the components back together and join them with a "-".
NSString *result = [cleanedUpComponentsWithoutBlanks componentsJoinedByString:@"-"];

Наслаждайтесь!

Ответ 9

Основываясь на ответах на английском языке, здесь представлено расширение строки для удаления любых нежелательных символов.

extension String {

func stripCharacters() -> String {
    var invalidCharacters = CharacterSet(charactersIn: ":/")
    invalidCharacters.formUnion(.newlines)
    invalidCharacters.formUnion(.illegalCharacters)
    invalidCharacters.formUnion(.controlCharacters)

    let newString = self
        .components(separatedBy: invalidCharacters)
        .joined(separator: "_")

    return newString
   }
}

Example:
let fileName = "Man(lop23/45"
let newFileName = fileName.stripCharacters()
print(newFileName)