我可以在IOS上使用tempnam吗?

时间:2011-03-21 15:27:47

标签: c++ objective-c ios

我正在将一个C ++ lib移植到iOS,并且遇到了代码调用tmpnam的问题。该函数返回“var / tmp / tmp.0.0xGlzv”,我假设它在我的应用程序允许播放的“沙箱”之外。次序fopen返回“Operation not allowed”。有可行的替代品吗?

4 个答案:

答案 0 :(得分:3)

怎么样?
[NSTemporaryDirectory() stringByAppendingPathComponent:@"myTempFile1.tmp"];

对于唯一的文件名,请尝试以下方法:

NSString *uniqueTempFile()
{
    int i = 1;
    while (YES)
    {
        NSString *currentPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%i.tmp", i]];
        if (![[NSFileManager defaultManager] fileExistsAtPath:currentPath])
            return currentPath;
        else
        {
            i++;
        }
    }
}

这很简单,但可能不是最有记忆效应的答案。

答案 1 :(得分:1)

我不知道你可以使用iostreams的任何替换,但回想一下,使用返回你打开的名字的函数会让你遇到竞争条件,其中另一个进程同时打开你的程序文件确定它没有不存在。

更安全的是使用类似tmpfile(man tmpfile)的东西,遗憾的是它返回一个C风格的FILE*而不是允许你使用iostreams。然而,编写一个使用字符串流包装然后将该流的内容作为文本写入FILE*的类将是微不足道的。

答案 2 :(得分:1)

我相信这是你真正想要的(文件没有扩展,所以如果你想要附加一个):

char *td = strdup([[NSTemporaryDirectory() stringByAppendingPathComponent:@"XXXXXX"] fileSystemRepresentation]);
int fd = mkstemp(td);
if(fd == -1) {
    NSLog(@"OPEN failed file %s %s", td, strerror(errno));
}
free(td);

答案 3 :(得分:1)

这是我正在使用的。此外,这是设置的,因此您可以在没有函数调用的情况下复制/粘贴内联。

- (NSString *)tempFilePath
{
    NSString *tempFilePath;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    for (;;) {
        NSString *baseName = [NSString stringWithFormat:@"tmp-%x.caf", arc4random()];
        tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:baseName];
        if (![fileManager fileExistsAtPath:tempFilePath])
            break;
    }
    return tempFilePath;
}