2014-06-18 23 views
5

में temp निर्देशिका एक्सेस करना मैं स्विफ्ट में temp निर्देशिका तक पहुंचने का प्रयास कर रहा था। ऑब्जेक्टिव-सी में, मैं ऐसा करने के लिए निम्नलिखित कोड का उपयोग कर सकता:स्विफ्ट

- (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; 
} 

हालांकि, मैं थोड़ा प्रकार रूपांतरण के बारे में भ्रमित कर रहा हूँ और स्विफ्ट के लिए ऑब्जेक्टिव-सी से कास्टिंग, जैसे const char * या CMutablePointer<CChar>। क्या कोई दस्तावेज है जिसमें मुझे देखना चाहिए?

धन्यवाद।

उत्तर

10

कैसे की तरह कुछ के बारे में:

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

यह चार * के बारे में आपके प्रश्न का उत्तर नहीं है, लेकिन यह क्लीनर है ...

NSFileManager संदर्भ here

अद्वितीय नामों के संबंध में this SO question भी देखें।

+3

ध्यान दें कि बीएसडी समारोह 'mkdtemp()' 'NSFileManager createDirectoryAtPath' विधि से अलग है क्योंकि यह दिया टेम्पलेट से कोई * अद्वितीय निर्देशिका का नाम * पैदा करता है। –

+0

@Grimxn धन्यवाद! मैं इसे बाद में कोशिश करूंगा। बीटीडब्ल्यू लगता है 'createDirectoryAtPath (पथ: स्ट्रिंग !, विशेषताएँ: NSDictionary!)' को बहिष्कृत किया गया है, अब यह 'createDirectoryAtURL है :IntermediateDirectories: विशेषताएँ: त्रुटि: '। और इसका मतलब है कि मैं उसी विधि के साथ एक temp फ़ाइल बनाने के लिए 'createFileAtPath() 'का उपयोग कर सकता हूं? –

+0

@MartinR तो अगर मैं createDirectoryAtPath का उपयोग करता हूं तो मुझे अपना अनूठा नाम बनाना होगा? –

2

स्विफ्ट करने के लिए अपने ऑब्जेक्टिव-सी कोड का एक सीधा अनुवाद होगा:

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() बीएसडी विधि का उपयोग करता। यह विधि टेम्पलेट से एक निर्देशिका नाम बनाता है जो उस समय मौजूद नहीं है जहां विधि कहा जाता है।

नैट कुक के लिए धन्यवाद, जो पता लगा है कि reinterpretCast(), UnsafePointer<CChar> एक CString रूप mkdtemp() द्वारा वापस इलाज के लिए इतना है कि यह stringWithFileSystemRepresentation() को पारित किया जा सकता इस्तेमाल किया जा सकता, Working with C strings in Swift, or: How to convert UnsafePointer<CChar> to CString देखते हैं।


Xcode 6 बीटा 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 
} 
8

स्विफ्ट 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

स्विफ्ट 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 
} 
+0

अन्य लोगों के लिए कुछ चीजें इसका उपयोग करना चाहते हैं: 1> आपने फ़ाइल एक्सटेंशन के साथ एक यूआरएल बनाया है, और इसमें एक फ़ोल्डर बना रहे हैं, और 2>, यह निर्देशिका शून्य हो जाएगी यदि निर्देशिका पहले से मौजूद है, जो हो सकता है वह व्यवहार हो जो आप (और मूल पोस्टर) चाहते हैं, लेकिन ज्यादातर मामलों में उपयोगकर्ता संभवतः एक परिणाम चाहता है भले ही निर्देशिका पहले से मौजूद हो। (इन दोनों चीजें अनचाहे हैं, लेकिन जब तक स्विफ्ट ओब्जे-सी के लिए अलग-अलग व्यवहार नहीं करता है, तो परिणाम मैं अपेक्षा करता हूं) – narco

2

स्विफ्ट 3 और ऊपर

मुझे लगता है कि तेज में यह करने के लिए एक अच्छा तरीका FileManager पर एक विस्तार के साथ है। यह एक अद्वितीय अस्थायी फ़ोल्डर बनाना चाहिए और आपको यूआरएल वापस कर देना चाहिए।

extension FileManager{ 

    func createTemporaryDirectoy() throws -> URL{ 
     let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString) 

     try self.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) 
     return url 
    } 
}