Какие символы разрешены в имени файла iOS? - PullRequest
21 голосов
/ 24 мая 2011

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

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

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

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

Ответы [ 8 ]

27 голосов
/ 30 августа 2013

Используйте 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:@"-"];
10 голосов
/ 12 сентября 2016

Я считаю, что это чище и, вероятно, намного более производительно.Это основано на решении Ангела Найденова, но сначала создается набор символов со всеми недопустимыми символами, а затем вызывается 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("")
9 голосов
/ 23 марта 2012

Мне пришлось сохранять удаленные файлы локально с именами файлов, содержащими другие символы, кроме основных буквенно-цифровых символов.Я использую метод ниже, чтобы удалить потенциально недопустимые символы, гарантируя, что это правильное имя файла для файловой системы при генерации 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]]
9 голосов
/ 24 мая 2011

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

То, что вы ищете, похоже на:

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

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

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

7 голосов
/ 15 января 2015

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

Сначала нам нужно узнать, что такоефайловая система, которую используют устройства 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, заключается в том, что он кажется мне слишком ограничительным.Я не хочу ограничивать своих пользователей только латинскими символами.С таким же успехом они могут захотеть использовать китайский, кириллицу и все, что им нравится.

Удачное кодирование!

2 голосов
/ 28 декабря 2018

Это расширение 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?/!!23$$@1asd".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"
1 голос
/ 26 октября 2017

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

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()
0 голосов
/ 23 марта 2017

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

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's 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:@"-"];

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

...