Доступ к временному каталогу в Swift
Я пытался получить доступ к временному каталогу в Swift. В Objective-C я мог бы использовать следующий код для этого:
- (NSString *)tempDirectory {
NSString *tempDirectoryTemplate =
[NSTemporaryDirectory() stringByAppendingPathComponent:@"XXXXX"];
const char *tempDirectoryTemplateCString = [tempDirectoryTemplate fileSystemRepresentation];
char *tempDirectoryNameCString = (char *)malloc(strlen(tempDirectoryTemplateCString) + 1);
strcpy(tempDirectoryNameCString, tempDirectoryTemplateCString);
char *result = mkdtemp(tempDirectoryNameCString);
if (!result) {
return nil;
}
NSString *tempDirectoryPath = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:tempDirectoryNameCString length:strlen(result)];
free(tempDirectoryNameCString);
return tempDirectoryPath;
}
Однако я немного запутался в преобразовании типов и кастингах из Objective-C в Swift, например const char *
или CMutablePointer<CChar>
. Есть ли какие-либо документы, на которые я должен смотреть?
Спасибо.
Ответы
Ответ 1
Как насчет чего-то типа:
func createTempDirectory() -> String? {
let tempDirectoryTemplate = NSTemporaryDirectory().stringByAppendingPathComponent("XXXXX")
let fileManager = NSFileManager.defaultManager()
var err: NSErrorPointer = nil
if fileManager.createDirectoryAtPath(tempDirectoryTemplate, withIntermediateDirectories: true, attributes: nil, error: err) {
return tempDirectoryTemplate
} else {
return nil
}
}
Он не отвечает на ваш вопрос о char *, но он чище...
Ссылка NSFileManager здесь.
Также проверьте этот вопрос SO относительно уникальных имен.
Ответ 2
версия Swift 2.1:
func createTempDirectory() -> String? {
let tempDirURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("XXXXXX")
do {
try NSFileManager.defaultManager().createDirectoryAtURL(tempDirURL, withIntermediateDirectories: true, attributes: nil)
} catch {
return nil
}
return tempDirURL.absoluteString
}
Ответ 3
версия Swift 3
func createTempDirectory() -> String? {
guard let tempDirURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("myTempFile.xxx") else {
return nil
}
do {
try FileManager.default.createDirectory(at: tempDirURL, withIntermediateDirectories: true, attributes: nil)
} catch {
return nil
}
return tempDirURL.absoluteString
}
Ответ 4
Прямой перевод вашего кода Objective-C в Swift будет:
func tempDirectory()->String! {
let tempDirectoryTemplate = NSTemporaryDirectory() + "XXXXX"
var tempDirectoryTemplateCString = tempDirectoryTemplate.fileSystemRepresentation().copy()
let result : CString = reinterpretCast(mkdtemp(&tempDirectoryTemplateCString))
if !result {
return nil
}
let fm = NSFileManager.defaultManager()
let tempDirectoryPath = fm.stringWithFileSystemRepresentation(result, length: Int(strlen(result)))
return tempDirectoryPath
}
В качестве исходного кода используется тот же метод mkdtemp()
BSD. Этот метод создает
имя каталога из шаблона, который, как гарантируется, не существует в то время, когда
вызывается метод.
Благодаря Nate Cook, который понял, что reinterpretCast()
может использоваться для обработки UnsafePointer<CChar>
, возвращаемого mkdtemp()
, как CString
, так что его можно передать в stringWithFileSystemRepresentation()
, см. Работа со строками C в Swift или: Как преобразовать UnsafePointer <CChar> в CString.
Начиная с Xcode 6 beta 6, reinterpretCast()
больше не требуется, и
выше код может быть упрощен до
func tempDirectory()->String! {
let tempDirectoryTemplate = NSTemporaryDirectory() + "XXXXX"
var tempDirectoryTemplateCString = tempDirectoryTemplate.fileSystemRepresentation()
let result = mkdtemp(&tempDirectoryTemplateCString)
if result == nil {
return nil
}
let fm = NSFileManager.defaultManager()
let tempDirectoryPath = fm.stringWithFileSystemRepresentation(result, length: Int(strlen(result)))
return tempDirectoryPath
}
Ответ 5
Свифт 3 и выше
Я думаю, что хороший способ сделать это в Swift с расширением на FileManager. Это должно создать уникальную временную папку и вернуть вам URL.
extension FileManager{
func createTemporaryDirectory() throws -> URL {
let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString)
try createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
return url
}
}