Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何使用Cocoa创建临时文件?_Objective C_Cocoa_File Io - Fatal编程技术网

Objective c 如何使用Cocoa创建临时文件?

Objective c 如何使用Cocoa创建临时文件?,objective-c,cocoa,file-io,Objective C,Cocoa,File Io,几年前,当我使用C#时,我可以轻松创建一个临时文件,并通过此函数获取其名称: Path.GetTempFileName(); 此函数将在临时目录中创建一个具有唯一名称的文件,并返回该文件的完整路径 在Cocoa API中,我能找到的最接近的东西是: NSTemporaryDirectory 我是否遗漏了一些明显的东西,或者没有内置的方法来实现这一点?您可以使用临时文件名。一种安全的方法是使用。[注意:这适用于iPhone SDK,而不是Mac OS SDK] 据我所知,SDK中没有这些函数(

几年前,当我使用C#时,我可以轻松创建一个临时文件,并通过此函数获取其名称:

Path.GetTempFileName();
此函数将在临时目录中创建一个具有唯一名称的文件,并返回该文件的完整路径

在Cocoa API中,我能找到的最接近的东西是:

NSTemporaryDirectory

我是否遗漏了一些明显的东西,或者没有内置的方法来实现这一点?

您可以使用临时文件名。

一种安全的方法是使用。

[注意:这适用于iPhone SDK,而不是Mac OS SDK]

据我所知,SDK中没有这些函数(与标准Mac OS X 10.5文件相比,
unistd.h
文件大幅缩减)。我会使用一些大致如下的内容:

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

不是最漂亮的,但是功能性的

您可以使用
NSTask
uuidgen
来获取唯一的文件名,然后将其附加到
NSTemporaryDirectory()
中的字符串中。这在Cocoa Touch上不起作用。不过这有点冗长。

我通过
NSFileManager
上的一个类别创建了一个纯可可解决方案,它使用了
NSTemporary()
和一个全局唯一ID的组合

这里是头文件:

@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:
来创建文件。

苹果提供了一种访问临时目录和为临时文件创建唯一名称的极好方法

- (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;
}
链接::: 请参阅文件:::AppDelegate.m

添加到@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;
}

如果目标是iOS 6.0或Mac OS X 10.8或更高版本:

NSString *tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSUUID UUID] UUIDString]];
Swift 5和Swift 4.2 或者Ssswift的oneliner:

let prefix = "blah"
let url2 = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(prefix)-\(UUID())")
print(url2)

实现这一点的现代方法是
FileManager


使用此方法,您可以指定一个临时目录,以确切说明您想要什么类型的临时目录。例如,
.cachesDirectory
将在两次运行之间保持(尽可能)并保存在用户库中,而
.itemReplacementDirectory
将与目标文件位于同一卷上。

不要使用类似于
NSTemporaryDirectory
的旧式API,从
FileManager
获取适当的
URL

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

您仍然需要创建目录。

mktemp(3)中有一个竞争条件,最好使用mkstemp(3)。这与mktemp(3)具有相同的竞争条件:将文件名的创建与临时文件的创建分离会打开一个漏洞窗口。按照Graham Lee的建议使用mkstemp(3)。对不起,我当时处于iPhone模式;原始海报中建议的mkstemp(3)很好,但它在iPhone上不起作用。在iPhone上,每个应用程序都有自己的文件系统子树。NSTemporaryDirectory()返回应用程序包中的某些内容。你仍然在与你自己和任何其他拥有tmp目录写入权限的人竞争,但我认为这只是特权进程。@Ken询问者说它们在iPhone上的什么地方?当从多个线程“同时”调用时,这会失败。我不知道该方法的粒度有多细(文档中没有详细说明),但对我来说,我的NSO操作调用得太快,并且文件的名称相同。我的解决方案是将NSOperations地址添加到文件名中,因为它们肯定会不同:[NSString stringWithFormat:@”%d_%.0f.%@“,self,[NSDate timeInterv…如果您只需要一个UUID,那么使用
NSTask
执行
uuidgen
有点过分了。请注意,10.8+有一个nsuid类来创建UUID,而不必离开Cocoa land:使用该C#API时要注意:它的命名空间只有65k个文件,一旦用完就会抛出异常。这在在生产中-并非所有程序都会认真清理其临时文件。此代码不再有效,但等效版本更简单:
URL(fileURLWithPath:NSTemporaryDirectory())。appendingPathComponent(“\(前缀)-\(UUID())”
Thank@Ssswift以稍微详细一点的方式更新了答案。不完全是“使用Cocoa”…更像是“使用POSIX”
let tmpURL = FileManager
    .default
    .temporaryDirectory
    .appendingPathComponent(UUID().uuidString)