views:

4764

answers:

6

Years ago when I was working with C# I could easily create a temporary file and get its name with this function:

Path.GetTempFileName();

This function would create a file with a unique name in the temporary directory and return the full path to that file.

In the Cocoa API's, the closest thing I can find is:

NSTemporaryDirectory

Am I missing something obvious or is there no built in way to do this?

+2  A: 

You could use mktemp to get a temp filename.

Giao
There's a race condition in mktemp(3), it's better to use mkstemp(3).
Graham Lee
+15  A: 

A safe way is to use mkstemp(3).

Graham Lee
@Chris Hanson: what, no x-man-page://3/mkstemp link? ;-)
Graham Lee
http://cocoawithlove.com/2009/07/temporary-files-and-folders-in-cocoa.html
Quinn Taylor
+5  A: 

[Note: This applies to the iPhone SDK, not the Mac OS SDK]

From what I can tell, these functions aren't present in the SDK (the unistd.h file is drastically pared down when compared to the standard Mac OS X 10.5 file). I would use something along the lines of:

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

Not the prettiest, but functional

Ben Gottlieb
This has the same race condition as mktemp(3): Separating creation of the filename from creation of the temporary file opens a window of vulnerability. Use mkstemp(3) as Graham Lee suggests.
Chris Hanson
Sorry, I was in iPhone mode; mkstemp(3) as suggested by the original poster is fine, but it won't work on iPhone.
Ben Gottlieb
On the iPhone, each app has its own subtree of the filesystem. NSTemporaryDirectory() returns something within the app bundle. You still race against yourself and against anything else that has write permission into your tmp dir, but I think that's only privileged processes.
Ken
@Ken where did the asker say they were on iPhone?
Graham Lee
Nowhere, other than in this answer that we're commenting on. :-) I was replying to the above. The lack of mkstemp on the phone is not as much of a problem on the phone as it would be on the mac.
Ken
+1  A: 

You could use an NSTask to uuidgen to get a unique file name, then append that to a string from NSTemporaryDirectory(). This won't work on Cocoa Touch. It is a bit long-winded though.

alextgordon
+3  A: 

Though it's nearly a year later, I figured it's still helpful to mention a blog post from Cocoa With Love by Matt Gallagher. http://cocoawithlove.com/2009/07/temporary-files-and-folders-in-cocoa.html He shows how to use mkstemp() for files and mkdtemp() for directories, complete with NSString conversions.

Quinn Taylor
+1  A: 

I created a pure Cocoa solution by way of a category on NSFileManager that uses a combination of NSTemporary() and a globally unique ID.

Here the header file:

@interface NSFileManager (TemporaryDirectory)

-(NSString *) createTemporaryDirectory;

@end

And the implementation file:

@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

This creates a temporary directory but could be easily adapted to use createFileAtPath:contents:attributes: instead of createDirectoryAtPath: to create a file instead.

Philipp