访问Swift中的临时目录

时间:2014-06-18 09:03:05

标签: objective-c macos cocoa 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>。有没有我应该研究的文件?

感谢。

6 个答案:

答案 0 :(得分:11)

如下:

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参考here

另请查看有关唯一名称的this SO question

答案 1 :(得分:8)

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
}

答案 2 :(得分: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
}

答案 3 :(得分:2)

将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,以便将其传递给{ {1}},请参阅Working with C strings in Swift, or: How to convert UnsafePointer<CChar> to CString


从Xcode 6 beta 6开始,stringWithFileSystemRepresentation()不再是必需的了 上面的代码可以简化为

reinterpretCast()

答案 4 :(得分:2)

Swift 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
    }
}

答案 5 :(得分:1)

根据苹果公司的说法,不鼓励使用NSTemporaryDirectory

请参阅FileManager方法的url(for:in:appropriateFor:create :) 查找正确的临时目录的首选方法。欲了解更多 有关临时文件的信息,请参见《文件系统编程指南》。

因此,您应该使用FileManager.default.temporaryDirectory

或者如果您想要唯一的路径:

let extractionPath = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)