Как мне создать временный файл с Какао?

Несколько лет назад, когда я работал с C#, я мог легко создать временный файл и получить его имя с помощью этой функции:

Path.GetTempFileName();

Эта функция создаст файл с уникальным именем во временном каталоге и вернет полный путь к этому файлу.

В API Какао самое близкое, что я могу найти, это:

NSTemporaryDirectory

Я что-то упускаю очевидное или нет встроенного способа сделать это?

11 ответов

Решение

Безопасный способ - использовать mkstemp (3).

[Примечание: это относится к iPhone SDK, а не к Mac OS SDK]

Из того, что я могу сказать, эти функции отсутствуют в SDK (unistd.h файл значительно сокращен по сравнению со стандартным файлом Mac OS X 10.5). Я хотел бы использовать что-то вроде:

[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"txt"]];

Не самый красивый, но функциональный

Apple предоставила отличный способ доступа к временному каталогу и создания уникальных имен для временных файлов.

- (NSString *)pathForTemporaryFileWithPrefix:(NSString *)prefix
{
    NSString *  result;
    CFUUIDRef   uuid;
    CFStringRef uuidStr;

    uuid = CFUUIDCreate(NULL);
    assert(uuid != NULL);

    uuidStr = CFUUIDCreateString(NULL, uuid);
    assert(uuidStr != NULL);

    result = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@", prefix, uuidStr]];
    assert(result != nil);

    CFRelease(uuidStr);
    CFRelease(uuid);

    return result;
}

ССЫЛКА:::: http://developer.apple.com/library/ios/#samplecode/SimpleURLConnections/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009245 см. Файл:::AppDelegate.m

Хотя это почти год спустя, я подумал, что все же полезно упомянуть пост в блоге "Какао с любовью" Мэтта Галлахера. http://cocoawithlove.com/2009/07/temporary-files-and-folders-in-cocoa.html Он показывает, как использовать mkstemp() для файлов и mkdtemp() для каталогов, в комплекте с преобразованиями NSString.

Я создал чистый раствор какао в виде категории на NSFileManager который использует комбинацию NSTemporary() и глобально уникальный идентификатор.

Вот заголовочный файл:

@interface NSFileManager (TemporaryDirectory)

-(NSString *) createTemporaryDirectory;

@end

И файл реализации:

@implementation NSFileManager (TemporaryDirectory)

-(NSString *) createTemporaryDirectory {
 // Create a unique directory in the system temporary directory
 NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString];
 NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:guid];
 if (![self createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil]) {
  return nil;
 }
 return path;
}

@end

Это создает временный каталог, но может быть легко адаптирован для использования createFileAtPath:contents:attributes: вместо createDirectoryAtPath: вместо этого создать файл.

Если используется iOS 6.0 или Mac OS X 10.8 или выше:

NSString *tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSUUID UUID] UUIDString]];

Обновлено для Swift 3, скопировано прямо с игровой площадки:

import Foundation

func pathForTemporaryFile(with prefix: String) -> URL {
    let uuid = UUID().uuidString
    let pathComponent = "\(prefix)-\(uuid)"
    var tempPath = URL(fileURLWithPath: NSTemporaryDirectory())
    tempPath.appendPathComponent(pathComponent)
    return tempPath
}

let url = pathForTemporaryFile(with: "blah")
print(url)

Современный способ сделать это FileManager "s url(for:in:appropriateFor:create:),

С помощью этого метода вы можете указать SearchPathDirectory точно сказать, какой временный каталог вы хотите. Например, .cachesDirectory будет сохраняться между запусками (насколько это возможно) и сохраняться в библиотеке пользователя, а .itemReplacementDirectory будет на том же томе, что и целевой файл.

Не используйте устаревшие API, например NSTemporaryDirectory, получите правильный URL вместо FileManager.

let tmpURL = FileManager
    .default
    .temporaryDirectory
    .appendingPathComponent(UUID().uuidString)

Вам все равно придется создать каталог.

Вы можете использовать mktemp, чтобы получить временное имя файла.

Вы могли бы использовать NSTask в uuidgen чтобы получить уникальное имя файла, а затем добавить его в строку из NSTemporaryDirectory(), Это не будет работать на Cocoa Touch. Это немного скучно, хотя.

Добавление в @Philipp:

- (NSString *)createTemporaryFile:(NSData *)contents {
    // Create a unique file in the system temporary directory
    NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString];
    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:guid];
    if(![self createFileAtPath:path contents:contents attributes:nil]) {
        return nil;
    }
    return path;
}
Другие вопросы по тегам