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