Какие символы разрешены в имени файла iOS?
Я ищу способ убедиться, что строка может использоваться в качестве имени файла под iOS. В настоящее время я нахожусь в разделе кода, который удаляет несовместимые символы. Мне интересно, правильно ли я это делаю.
NSString *filename = @"A file name";
fileName = [fileName stringByTrimmingCharactersInSet: [NSCharacterSet controlCharacterSet]];
fileName = [fileName stringByTrimmingCharactersInSet: [NSCharacterSet newlineCharacterSet]];
мне также интересно, есть ли уже метод, который проверяет строку как имя файла.
Спасибо за ваш совет!
7 ответов
прежде всего, вы используете неправильный метод. Обрезка строки приведет только к удалению символов в начале и конце строки.
то, что вы ищете, больше похоже на:
fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
однако это неоптимальное решение, так как вам придется делать это для каждого символа, который вы хотите исключить, поэтому, возможно, вы хотите продолжать искать или писать, что у вас есть собственный метод для управления строкой.
iOS основан на UNIX и как таковой я полагаю, что это поддерживает практически любые символы в именах файлов. UNIX допускает пробелы, , |, \, :, (, ), &, ;, а также подстановочные знаки, такие как ? и *, чтобы быть в кавычках или экранировать с помощью символа\. Однако я бы не использовал ни один из этих символов в своих именах файлов. Фактически, я бы ограничил символы в моих именах файлов "a" - "z', '0'-'9', '_' и".'.
Использовать Регулярное Выражение:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^a-zA-Z0-9_]+" options:0 error:nil];
filename = [regex stringByReplacingMatchesInString:filename options:0 range:NSMakeRange(0, filename.length) withTemplate:@"-"];
мне пришлось сохранять удаленные файлы локально с именами файлов, содержащими другие символы, кроме основных буквенно-цифровых символов. Я использую метод ниже, чтобы удалить потенциальные недопустимые символы, гарантируя, что это допустимое имя файла для файловой системы при создании 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]]
Я нахожу это более чистым и, вероятно, гораздо более эффективным. Это основано на решении Ангела Найденова, но сначала построение набора символов со всеми недопустимыми символами, а затем вызов 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("")
поскольку я не видел список с разрешенными символами в этом вопросе, но вопрос хотел список с такими символами, я добавляю немного больше деталей по этой теме.
Сначала нам нужно знать, что такое файловая система, которую используют устройства 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("/"))
причина, по которой я не предпочитаю подход регулярных выражений, заключается в том, что он кажется мне слишком ограничительным. Я не хочу ограничивать своих пользователей только латинскими символами. Они также могут захотеть использовать китайский, кириллицу или что-то еще, что им нравится.
удачи в кодировании!
Я придумал следующее решение. Пока неплохо работает.
import Foundation
extension String {
func removeUnsupportedCharactersForFileName() -> String {
var cleanString = self
["?", "/", "\", "*"].forEach {
cleanString = cleanString.replacingOccurrences(of: , with: "-")
}
return cleanString
}
}
let a = "***???foo.png"
let validString = a.removeUnsupportedCharactersForFileName()
Я очень доволен этим решением:
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:@"-"];
наслаждайтесь!