保存文件,避免重复的文件名和覆盖

时间:2012-10-16 10:51:20

标签: objective-c macos cocoa file

所以,这是我的情况:

  • 我有一个应用程序提示用户选择一个文件夹来保存他的文件
  • 现在让我们说他的文件是:a.pngb.pngc.png

我想要的是:

  • 如果文件 - 假设 - a.png已存在于所选文件夹中,请勿覆盖它。而是创建一个名为a (1).png的文件。如果文件a (1).png已经存在,则将其命名为a (2).png,依此类推 - 非常类似于OS X在复制粘贴具有相同名称的文件时所做的。

这就是我目前正在做的事情 - 但它仍然没有让我感到满意:

NSString* target = [self getTargetPathForFile:filename path:folder];

NSString* fname = [target lastPathComponent];

while ([[NSFileManager defaultManager] fileExistsAtPath: [folder stringByAppendingPathComponent:fname]])
{
    //NSLog(@"FNAME : %@",fname);

    if ([self str:fname containsString:@")." options:nil])
    {
        NSArray* a = [fname componentsSeparatedByString:@"("];
        NSArray* b = [[a objectAtIndex:1] componentsSeparatedByString:@")"];

        fname = [NSString stringWithFormat:@"%@(%d)%@",[a objectAtIndex:0],[[b objectAtIndex:0] intValue]+1,[b objectAtIndex:1]];
    }
    else
    {
        fname = [NSString stringWithFormat:@"%@ (1).%@",[fname stringByDeletingPathExtension],[fname pathExtension]];
    }

    //NSLog(@"Setting filename to :: %@",fname);
}
target = [folder stringByAppendingPathComponent:fname];

任何想法如何解决这个问题?是否有任何Cocoa友好(或内置)方法?

2 个答案:

答案 0 :(得分:8)

为什么不尝试这个:

NSString* fname = [target lastPathComponent];
NSString* fnameNoExt = [fname stringByDeletingPathExtension];
NSString* extension = [fname pathExtension];

int fileIndex = 1;
while ([[NSFileManager defaultManager] fileExistsAtPath: [folder stringByAppendingPathComponent:fname]])
{
    //NSLog(@"FNAME : %@",fname);
    fname = [NSString stringWithFormat:@"%@ (%d).%@", fnameNoExt, fileIndex, extension];
    //NSLog(@"Setting filename to :: %@",fname);
    fileIndex++;
}
target = [folder stringByAppendingPathComponent:fname];

答案 1 :(得分:1)

如果您不像在评论中所解释的那样关心文件名,并且可以考虑使用自动生成的文件名,请使用CFUUIDNSProcessInfo或{ {1}}。

  • 使用mkstemp生成唯一标识符CFUUID

    str
  • 使用CFUUIDRef uuidref = CFUUIDCreate(NULL); CFStringRef cfstr = CFUUIDCreateString(NULL, uuidref); // If using ARC: NSString* filename = (__bridge_transfer NSString*)cfstr; // If not using ARC NSString* filename = [(NSString*)cfstr autorelease]; // Then release the CFUUIDRef CFRelease(uuidref);

    NSProcessInfo
  • 使用NSString* filename = [[NSProcessInfo processInfo] globallyUniqueString]; :请参阅CocoaWithLove