2011-03-21 76 views
3

我將一個C++ lib移植到iOS,並遇到代碼調用tmpnam的問題。該函數返回「var/tmp/tmp.0.0xGlzv」,我認爲它在允許我的應用程序播放的「沙箱」之外。後續fopen返回「操作不允許」。有沒有可行的替代品?我可以使用tempnam和IOS嗎?

回答

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++; 
     } 
    } 
} 

這很簡單,但可能不是最內存efficent答案。

+0

這讓我進入了沙箱的可接受區域。現在生成一個唯一的文件名。 – tillerstarr 2011-03-21 16:17:15

+0

@tillerstarr檢查我的更新 – 2011-03-21 16:23:15

1

我不知道任何可以用於iostreams的替換,但回想一下,使用函數返回一個後來打開的名稱會使您遇到競爭狀況,在這種情況下,另一個進程將同時打開文件並確定它不存在。

更安全的是使用類似tmpfile(man tmpfile)的東西,不幸的是它返回的是C風格FILE*,而不是允許您使用iostream。然而,編寫一個使用stringstream進行封裝的類,然後將該文件的內容作爲文本寫入FILE*將是微不足道的。

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); 
+1

這裏有一個提示 - 千萬不要在C'template中命名變量。它會導致太多的錯誤,如果您需要在後續的C++中進行交互操作。 – 2013-02-14 18:02:47

+0

@ RichardJ.RossIII啊,我明白你的意思了 - 對不起 - 這只是示例代碼。我會解決它。 – 2013-02-14 23:38:35

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; 
} 
+1

你的函數應該'return tempFilePath;':) – 2013-11-21 17:46:33