NSFileManager уникальные имена файлов - PullRequest
37 голосов
/ 13 октября 2011

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

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

Ответы [ 9 ]

75 голосов
/ 13 октября 2011

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

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];
8 голосов
/ 25 февраля 2013

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

Вы также можете использовать почтенный 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(), который создает файл и возвращает дескриптор файла.

5 голосов
/ 15 июля 2014

В iOS 6 самый простой способ - использовать:

NSString *uuidString = [[NSUUID UUID] UUIDString];
4 голосов
/ 29 января 2016

Вот что я использовал в Swift 3.0

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

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

    print("uniqueFileName: \(uniqueFileName)")

    return uniqueFileName
}
2 голосов
/ 13 октября 2011

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

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

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

1 голос
/ 21 декабря 2018

Swift 4.2, я использую два варианта, один в основном уникальный, но читаемый, а другой просто уникальный.

// Create a unique filename, added to a starting string or not
public func uniqueFilename(filename: String = "") -> String {
    let uniqueString = ProcessInfo.processInfo.globallyUniqueString
    return filename + "-" + uniqueString
}

// Mostly Unique but Readable ID based on date and time that is URL compatible ("unique" to nearest second)
public func uniqueReadableID(name: String = "") -> String {

    let timenow = DateFormatter.localizedString(from: Date(), dateStyle: .medium, timeStyle: .medium)
    let firstName = name + "-" + timenow
    do {
        // Make ID compatible with URL usage
        let regex = try NSRegularExpression(pattern: "[^a-zA-Z0-9_]+", options: [])
        let newName = regex.stringByReplacingMatches(in: firstName, options: [], range: NSMakeRange(0, firstName.count), withTemplate: "-")
        return newName
    }
    catch {
        print("? Unique ID Error: \(error.localizedDescription)")
        return uniqueFilename(filename: name)
    }
}
1 голос
/ 02 января 2018

Super-easy Swift 4 1-вкладыш:

fileName = "MyFileName_" + UUID().uuidString

или

fileName = "MyFileName_" + ProcessInfo().globallyUniqueString
0 голосов
/ 20 июня 2018

Swift 4.1.Просто передайте имя расширения файла, и функция вернет уникальное имя файла.

func uniqueFileNameWithExtention(fileExtension: String) -> String {
        let uniqueString: String = ProcessInfo.processInfo.globallyUniqueString
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMddhhmmsss"
        let dateString: String = formatter.string(from: Date())
        let uniqueName: String = "\(uniqueString)_\(dateString)"
        if fileExtension.length > 0 {
            let fileName: String = "\(uniqueName).\(fileExtension)"
            return fileName
        }

        return uniqueName
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...