Objective-C
Cocoa

重複しないファイル名

More than 3 years have passed since last update.

ファイルやフォルダの書き出しをするとき、既に同名のファイルが存在していた場合は重複しないような名前を生成したい。

実はこの働きをする-[NSFileManager _web_pathWithUniqueFilenameForPath:]という隠しメソッドが存在するらしいのだが、なんとなく不安なのでこの程度ならいっそ書いてしまえ!
というわけで、NSFileManagerにカテゴリを追加。

@interface NSFileManager (NSFileManagerUniquePathExtention)
- (NSString *)pathWithUniqueFilenameForPath:(NSString *)path;
@end

@implementation NSFileManager (NSFileManagerUniquePathExtention)

- (NSString *)pathWithUniqueFilenameForPath:(NSString *)path {
    if (![self fileExistsAtPath:path]) return [path lastPathComponent];

    NSString *extention = [path pathExtension];
    NSString *base = [path stringByDeletingPathExtension];

    if (extention.length > 0) extention = [@"." stringByAppendingString:extention];

    NSString *prefixZero = @"";
    while ([path length] + [prefixZero length] < NSUIntegerMax) {
        for (NSUInteger i = 1; i < NSUIntegerMax; i++) {
            NSString *result = [NSString stringWithFormat:@"%@-%@%lu%@", base, prefixZero, i, extention];
            if (![self fileExistsAtPath:result]) return result;
        }

        prefixZero = [prefixZero stringByAppendingString:@"0"];
    }

    return nil;
}

@end

ファイル、フォルダのどちらでも使える。
「hoge.txt」が「hoge-1.txt」「hoge-2.txt」のようになる。
後ろの数値がNSUIntegerMaxまでいくとは思わないが、そのような場合は数字の前に0を追加する。
whileループを抜ける条件は適当。無限ループにならなければ良い。