36

Ho bisogno di un modo rapido e semplice per archiviare file con nomi di file univoci su iOS. Ho bisogno di aggiungere il prefisso al file con una stringa e quindi aggiungere l'identificativo univoco generato alla fine. Speravo che NSFileManager avesse un metodo conveniente per farlo, ma non riesco a trovarlo.Nome file esclusivo NSFileManager

Stavo guardando createFileAtPath:contents:attributes:, ma non sono sicuro se gli attributi mi daranno quel nome di file univoco.

+1

Questo [SO] [1] potrebbe essere è quello che ti serve. [1]: http://stackoverflow.com/questions/215820/how-do-i-create-a-temporary-file-with-cocoa – user523234

risposta

75

Creare il proprio nome del file:

CFUUIDRef uuid = CFUUIDCreate(NULL); 
CFStringRef uuidString = CFUUIDCreateString(NULL, uuid); 
CFRelease(uuid); 
NSString *uniqueFileName = [NSString stringWithFormat:@"%@%@", prefixString, (NSString *)uuidString]; 
CFRelease(uuidString); 

Una semplice proposta da @darrinm nei commenti alternativa:

NSString *prefixString = @"MyFilename"; 

NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ; 
NSString *uniqueFileName = [NSString stringWithFormat:@"%@_%@", prefixString, guid]; 

NSLog(@"uniqueFileName: '%@'", uniqueFileName); 

NSLog uscita:
uniqueFileName: 'MyFilename_680E77F2-20B8-444E-875B -11453B06606E-688-00000145B460AF51 '

Nota: iOS6 ha introdotto la classe NSUUID che può essere utilizzata al posto di CFUUID.

NSString *guid = [[NSUUID new] UUIDString]; 
+12

Una bella scorciatoia per ottenere una stringa GUID è: NSString * guid = [[NSProcessInfo processInfo] globallyUniqueString] – darrinm

+1

È grandioso, ma qual è la probabilità di collisioni? – Arsynth

+0

@ user578205 Dai documenti: Un UUID è reso unico sia nello spazio che nel tempo combinando un valore univoco per il computer su cui è stato generato e un valore che rappresenta il numero di intervalli di 100 nanosecondi. C'è una ragione per cui sono chiamati "unici". – zaph

7

È inoltre possibile utilizzare il venerabile mktemp() (vedi man 3 mktemp). Come questo:

- (NSString*)createTempFileNameInDirectory:(NSString*)dir 
{ 
    NSString* templateStr = [NSString stringWithFormat:@"%@/filename-XXXXX", dir]; 
    char template[templateStr.length + 1]; 
    strcpy(template, [templateStr cStringUsingEncoding:NSASCIIStringEncoding]); 
    char* filename = mktemp(template); 

    if (filename == NULL) { 
    NSLog(@"Could not create file in directory %@", dir); 
    return nil; 
    } 
    return [NSString stringWithCString:filename encoding:NSASCIIStringEncoding]; 
} 

Il XXXXX sarà sostituito con una combinazione di lettere/numero univoco. Possono essere visualizzati solo alla fine del modello, quindi non è possibile aggiungere un'estensione nel modello (anche se è possibile aggiungerla dopo aver ottenuto il nome file univoco). Aggiungi il numero X come desideri nel modello.

Il file non viene creato, è necessario crearlo manualmente. Se si hanno più thread che creano file unici nella stessa directory, si ha la possibilità di avere condizioni di gara. In tal caso, utilizzare mkstemp() che crea il file e restituisce un descrittore di file.

+2

Si può effettivamente avere un'estensione .. 'percorso = @" .../XXXXXX.pdf "' e quindi fare 'mkstemps (path, suffixLength)'. 'suffixLength = 4' in questo caso. – Marc

8

Uso la data corrente per generare un nome di file casuale con una determinata estensione. Questo è uno dei metodi nella mia categoria NSFileManager:

 
+ (NSString*)generateFileNameWithExtension:(NSString *)extensionString 
{ 
    // Extenstion string is like @".png" 

    NSDate *time = [NSDate date]; 
    NSDateFormatter* df = [NSDateFormatter new]; 
    [df setDateFormat:@"dd-MM-yyyy-hh-mm-ss"]; 
    NSString *timeString = [df stringFromDate:time]; 
    NSString *fileName = [NSString stringWithFormat:@"File-%@%@", timeString, extensionString]; 

    return fileName; 
} 
+3

ATTENZIONE: l'uso della data può causare collisioni durante l'ora legale -1. (In autunno quando si ripete la stessa ora.) – bob

+1

Per evitare collisioni quando cambia l'ora legale, è possibile aggiungere l'identificatore "Z" alla stringa del formato della data (rappresenta l'offset del fuso orario corrente). Forse questo aiuterà qualcuno. – Storix

5

In iOS 6 il metodo più semplice è quello di utilizzare:

NSString *uuidString = [[NSUUID UUID] UUIDString]; 
4

Ecco quello che ho finito per usare a Swift 3.0

public func generateUniqueFilename (myFileName: String) -> String { 

    let guid = ProcessInfo.processInfo.globallyUniqueString 
    let uniqueFileName = ("\(myFileName)_\(guid)") 

    print("uniqueFileName: \(uniqueFileName)") 

    return uniqueFileName 
} 
+1

Per Swift 3: let guid = ProcessInfo.processInfo.globallyUniqueString – user3717478

+0

Grazie! Aggiornato la mia risposta. –

0

Super-facile Swift 4 1-liner:

fileName = "MyFileName_" + UUID().uuidString 

o

fileName = "MyFileName_" + ProcessInfo().globallyUniqueString