36

iOS上で一意のファイル名を持つファイルをすばやく簡単に保存する必要があります。ファイルの先頭に文字列をつけ、生成された一意の識別子を末尾に追加する必要があります。 NSFileManagerには便利な方法がいくつかありましたが、見つけられないようです。NSFileManager固有のファイル名

私はcreateFileAtPath:contents:attributes:を見ていましたが、その属性が私にその一意のファイル名を与えるかどうかはわかりません。

+1

この[SO] [1]であるかもしれない何が必要です。 [1]:GUID文字列を取得するhttp://stackoverflow.com/questions/215820/how-do-i-create-a-temporary-file-with-cocoa – user523234

答えて

75

独自のファイル名を作成します。

CFUUIDRef uuid = CFUUIDCreate(NULL); 
CFStringRef uuidString = CFUUIDCreateString(NULL, uuid); 
CFRelease(uuid); 
NSString *uniqueFileName = [NSString stringWithFormat:@"%@%@", prefixString, (NSString *)uuidString]; 
CFRelease(uuidString); 

シンプルなコメントで@darrinmによって提案された代替:

NSString *prefixString = @"MyFilename"; 

NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ; 
NSString *uniqueFileName = [NSString stringWithFormat:@"%@_%@", prefixString, guid]; 

NSLog(@"uniqueFileName: '%@'", uniqueFileName); 

のNSLog出力:
uniqueFileName:「MyFilename_680E77F2-20B8-444E-875B -11453B06606E-688-00000145B460AF51 '

注:iOS6は、CFUUIDの代わりに使用できるNSUUIDクラスを導入しました。

NSString *guid = [[NSUUID new] UUIDString]; 
+12

素敵なショートカットは以下のとおりです。 NSString * guid = [[NSProcessInfo processInfo] globallyUniqueString] – darrinm

+1

それは素晴らしいですが、衝突の確率はどのくらいですか? – Arsynth

+0

@ user578205ドキュメントから:UUIDは、それが生成されたコンピュータに固有の値と100ナノ秒の間隔の数を表す値とを組み合わせることによって、時空間でユニークになる。彼らが「ユニーク」と呼ばれる理由があります。 – zaph

2

これはおそらく、あなたのために働く必要があります。

http://vgable.com/blog/2008/02/24/creating-a-uuid-guid-in-cocoa/

ポストの著者がNSStringののカテゴリとして「stringWithUUID」メソッドを実装示唆しています。このメソッドで生成されたGUIDを、作成しているファイル名の末尾に追加してください。

7

あなたが使用することもでき由緒あるmktemp()man 3 mktempを参照してください)。このように:

- (NSString*)createTempFileNameInDirectory:(NSString*)dir 
{ 
    NSString* templateStr = [NSString stringWithFormat:@"%@/filename-XXXXX", dir]; 
    char template[templateStr.length + 1]; 
    strcpy(template, [templateStr cStringUsingEncoding:NSASCIIStringEncoding]); 
    char* filename = mktemp(template); 

    if (filename == NULL) { 
    NSLog(@"Could not create file in directory %@", dir); 
    return nil; 
    } 
    return [NSString stringWithCString:filename encoding:NSASCIIStringEncoding]; 
} 

XXXXXは、固有の文字/数字の組み合わせに置き換えられます。テンプレートの末尾にのみ表示されるので、テンプレートに拡張子を付けることはできません(一意のファイル名を取得した後で追加することはできますが)。テンプレートに必要な数だけXを追加します。

ファイルが作成されていないため、自分で作成する必要があります。同じディレクトリに一意のファイルを作成するスレッドが複数ある場合は、競合条件が発生する可能性があります。この場合、mkstemp()を使用してファイルを作成し、ファイル記述子を返します。

+2

実際には、 'path = @" .../XXXXXX.pdf "という拡張子をつけてから' mkstemps(path、suffixLength) 'を実行することができます。 'suffixLength = 4'となります。 – Marc

8

現在の日付を使用して、指定された拡張子を持つランダムなファイル名を生成します。これは私のNSFileManagerカテゴリの方法の一つである:

のiOS 6では
 
+ (NSString*)generateFileNameWithExtension:(NSString *)extensionString 
{ 
    // Extenstion string is like @".png" 

    NSDate *time = [NSDate date]; 
    NSDateFormatter* df = [NSDateFormatter new]; 
    [df setDateFormat:@"dd-MM-yyyy-hh-mm-ss"]; 
    NSString *timeString = [df stringFromDate:time]; 
    NSString *fileName = [NSString stringWithFormat:@"File-%@%@", timeString, extensionString]; 

    return fileName; 
} 
+3

警告:日付を使用すると、夏時間-1の間に衝突が発生する可能性があります。 (同じ時間が繰り返される秋に) – bob

+1

夏時間の変更時の衝突を防ぐために、日付フォーマット文字列に "Z"指定子を追加することができます(現在のタイムゾーンオフセットを表します)。多分これは誰かを助けるでしょう。 – Storix

5

最も簡単な方法は、使用することです。ここでは

NSString *uuidString = [[NSUUID UUID] UUIDString]; 
4

は、私はスウィフト3で使用して終了するものです。0

public func generateUniqueFilename (myFileName: String) -> String { 

    let guid = ProcessInfo.processInfo.globallyUniqueString 
    let uniqueFileName = ("\(myFileName)_\(guid)") 

    print("uniqueFileName: \(uniqueFileName)") 

    return uniqueFileName 
} 
+1

Swift 3の場合:guid = ProcessInfo.processInfo.globallyUniqueString – user3717478

+0

ありがとう!私の答えを更新しました。 –

0

超簡単スウィフト4 1 - ライナー:

fileName = "MyFileName_" + UUID().uuidString 

または

fileName = "MyFileName_" + ProcessInfo().globallyUniqueString 
関連する問題