36

Мне нужен быстрый и простой способ хранения файлов с уникальными именами файлов в iOS. Мне нужно префикс файла со строкой, а затем добавить сгенерированный уникальный идентификатор до конца. Я надеялся, что у NSFileManager был удобный способ сделать это, но я не могу найти его.NSFileManager уникальные имена файлов

Я смотрел createFileAtPath:contents:attributes:, но не уверен, что атрибуты дадут мне это уникальное имя файла.

+1

Это [SO] [1] может быть то, что вам нужно. [1]: http://stackoverflow.com/questions/215820/how-do-i-create-a-temporary-file-with-cocoa – user523234

ответ

75

Создайте свое собственное имя файла:

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

Более простой альтернативой, предложенный @darrinm в комментариях:

NSString *prefixString = @"MyFilename"; 

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

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

NSLog выход:
uniqueFileName: «MyFilename_680E77F2-20B8-444E-875B -11453B06606E-688-00000145B460AF51 '

Примечание: iOS6 представил класс NSUUID, который можно использовать вместо CFUUID.

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

Хороший ярлык, чтобы получить строку GUID является: NSString * guid = [[NSProcessInfo processInfo] globallyUniqueString] – darrinm

+1

Это здорово, но какова вероятность столкновения? – Arsynth

+0

@ user578205 Из документов: UUID уникален как по пространству, так и по времени, комбинируя значение, уникальное для компьютера, на котором он был сгенерирован, и значение, представляющее число интервалов в 100 нс. Есть причина, по которой они называются «уникальными». – zaph

2

Это, вероятно, работать для вас:

http://vgable.com/blog/2008/02/24/creating-a-uuid-guid-in-cocoa/

автор поста предлагает реализовать метод «stringWithUUID» в качестве категории NSString. Просто добавьте GUID, сгенерированный с помощью этого метода, в конец создаваемого вами имени файла.

7

Вы также можете использовать почтенный mktemp() (см man 3 mktemp). Как это:

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

XXXXX будет заменен с уникальной комбинацией буквы/цифры. Они могут появляться только в конце шаблона, поэтому вы не можете иметь расширение, добавленное в шаблон (хотя вы можете добавить его после получения уникального имени файла). Добавьте как можно больше X в шаблон.

Файл не создан, вам необходимо создать его самостоятельно. Если у вас несколько потоков, создающих уникальные файлы в одном каталоге, вы можете использовать условия гонки. Если это так, используйте mkstemp(), который создает файл и возвращает дескриптор файла.

+2

На самом деле вы можете иметь расширение .. 'path = @" .../XXXXXX.pdf ", а затем сделать' mkstemps (path, suffixLength) '. 'suffixLength = 4' в этом случае. – Marc

8

Я использую текущую дату для генерации случайного имени файла с заданным расширением. Это один из методов в моей категории 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

ВНИМАНИЕ: Использование даты может привести к столкновениям во время летнего времени -1. (Осенью, когда один и тот же час повторяется.) – bob

+1

Во избежание коллизий при изменении летнего времени мы можем добавить спецификатор «Z» в строку формата даты (он представляет собой текущее смещение часового пояса). Может быть, это поможет кому-то. – Storix

5

В IOS 6 самый простой способ заключается в использовании:

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

Вот что я закончил с использованием в Swift 3.0

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

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

    print("uniqueFileName: \(uniqueFileName)") 

    return uniqueFileName 
} 
+1

Для Swift 3: let guid = ProcessInfo.processInfo.globallyUniqueString – user3717478

+0

Спасибо! Обновлен мой ответ. –

0

Супер-легкий Swift 4 1-лайнер:

fileName = "MyFileName_" + UUID().uuidString 

или

fileName = "MyFileName_" + ProcessInfo().globallyUniqueString