views:

60

answers:

5

Hi

My application generates loads of images and in order to save memory, I write these files to the temporary directory and read them when needed. I write two versions of the same image to the tmp folder one the thumbnail version at lower resolution and the other is full size. To make the file names unpredictable, I add a string hash at the end.

For instance I want to have two images one called "ThumbnailImage.fgl8bda" and the other "FullImage.fgl8bda"

This is the code I use:

NSString *fileName = @"Image.XXXXXXX";
NSString *thumbName = [@"Thumbnail" stringByAppendingFormat:@"%@", fileName];
NSString * thumbPath = [self writeToTempFile:thumbNailImage andName: thumbName];

NSString *fullName = [@"Full" stringByAppendingFormat:@"%@", fileName];
NSString *fullPath = [self writeToTempFile:fullImage andName: fullName];

However, the two files come out with different names, i.e. each time I use the fileName variable the hash is regenerated. For instance, my two images are called "ThumbnailImage.jhu078l" and "FullImage.ksi9ert".

Any idea how I can use the same hash more than once?

+2  A: 

It is generally not safe to reuse a temporary file name suffix, because even if you can ensure A.ashkjd does not exist, there is a chance B.ashkjd is occupied.

You could construct a folder and store the two images in it, e.g.

char tmpl[] = "Image.XXXXXX";
char* res = mkdtemp(tmpl);
if (res != NULL) {
   NSString* dirName = [NSString stringWithUTF8String:res];
   NSString* thumbPath = [dirName stringByAppendingPathComponent:@"Thumbnail.png"];
   [thumbImage writeToFile:thumbPath atomically:YES];
   NSString* fullPath = [dirName stringByAppendingPathComponent:@"Full.png"];
   [fullImage writeToFile:fullPath atomically:YES];
}

(Note: you need to remove the folder manually.)

KennyTM
Thanks very much. Will do so. That was very helpful.
ar106
A: 

I'm new to objc so apologies if this is a stupid suggestion. What happens if you use stringByAppendingString instead of description that you're invoking:

NSString *thumbName = [@"Thumbnail" stringByAppendingString:fileName];

I don't see why the two aren't equivalent for this usage, but still.

Also, how/where are you generating the hash?

EDIT

@ar06 I think you're saying that your (I'm assuming it's your) writeToTempFile method does a replace on the XXXXX' in the fileName parameter to a random value. If so then there's your problem - it generates a new random every time it's called, and you're calling it twice. The code fragment you posted does work, because fileName is immutable; it will save with a 'XXXXX' extension.

Do you need to refer to these random suffixes later? Whatever mechanism you use for tracking them could be also used by writeToTempFile to attach the same value to the thumb and the fullsize.

FWIW I agree that Kenny's approach is better since you can't guarantee uniqueness.

Tim Kemp
A: 

@TimG

It doesn't really make a difference. That too ends up in different names.

When I write

NSString *fileName = @"Image.XXXXXXX";

The XXXXXXX part of the fileName is replaced by 7 random characters so that the filenames are not predictable.

Cheers

ar106
+1  A: 

@KennyTM has a correct solution, but he didn't explain the cause.

writeToTempFile does not use a hash to fill in the unique part of the name. Instead, it uses a new unique random string for each call.

Darron
A: 

@TimG

As @Darron said, my writeToTempFile does not use a hash to fill in unique part of the name. Instead, it uses a new unique random string for each call. Hence, they end up with different names. So yes you're right. Calling the method twice was causing the problem.

Generally speaking using @KennyTm 's approach is more robust. This is what I do now.

ar106