web-dev-qa-db-fra.com

NSFileManager noms de fichiers uniques

J'ai besoin d'un moyen rapide et facile de stocker des fichiers avec des noms de fichiers uniques sur iOS. Je dois préfixer le fichier avec une chaîne, puis ajouter l'identifiant unique généré à la fin. J'espérais que NSFileManager disposait d'une méthode pratique pour le faire, mais je n'arrive pas à le trouver.

Je regardais createFileAtPath:contents:attributes:, mais je ne sais pas si les attributs me donneront ce nom de fichier unique.

37
spentak

Créez votre propre nom de fichier:

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

Une alternative plus simple proposée par @darrinm dans les commentaires:

NSString *prefixString = @"MyFilename";

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

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

Sortie NSLog:
uniqueFileName: 'MyFilename_680E77F2-20B8-444E-875B-11453B06606E-688-00000145B460AF51'

Remarque: iOS6 a introduit la classe NSUUID qui peut être utilisée à la place de CFUUID.

NSString *guid = [[NSUUID new] UUIDString];
75
zaph

J'utilise la date actuelle pour générer un nom de fichier aléatoire avec une extension donnée. Voici l'une des méthodes de ma catégorie NSFileManager: 

 + (NSString *) generateFileNameWithExtension: (NSString *) extensionString 
 {
 // La chaîne d'extension ressemble à @ ". Png" 

 NSDate * time = [NSDate date]; 
 NSDateFormatter * df = [NSDateFormatter new]; 
 [df setDateFormat: @ "jj-MM-aaaa-hh-mm-ss"]; 
 NSString * timeString = [df stringFromDate: time]; 
 NSString * fileName = [NSString stringWithFormat: @ "Fichier -% @% @", timeString, extensionString];; return fileName; 
} 
8
wzbozon

Vous pouvez également utiliser la vénérable mktemp() (voir man 3 mktemp). Comme ça:

- (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];
}

La XXXXX sera remplacée par une combinaison unique lettre/chiffre. Ils ne peuvent apparaître qu'à la fin du modèle, vous ne pouvez donc pas ajouter une extension au modèle (bien que vous puissiez l'ajouter après l'obtention du nom de fichier unique). Ajoutez autant de X que vous le souhaitez dans le modèle.

Le fichier n'est pas créé, vous devez le créer vous-même. Si plusieurs threads créent des fichiers uniques dans le même répertoire, vous pouvez éventuellement avoir des conditions de concurrence. Si tel est le cas, utilisez mkstemp() qui crée le fichier et retourne un descripteur de fichier.

7
ovidiu

Dans iOS 6, la méthode la plus simple consiste à utiliser:

NSString *uuidString = [[NSUUID UUID] UUIDString];
5
Reefwing

Voici ce que j'ai fini par utiliser dans Swift 3.0

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

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

    print("uniqueFileName: \(uniqueFileName)")

    return uniqueFileName
}
4
Dave Levy

Cela devrait probablement fonctionner pour vous:

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

L'auteur du message suggère d'implémenter une méthode 'stringWithUUID' en tant que catégorie de NSString. Ajoutez simplement un GUID généré avec cette méthode à la fin du nom de fichier que vous créez.

2
lottscarson

Swift 4.2, j’utilise deux options, l’une essentiellement unique mais lisible, et l’autre tout à fait unique. 

// Create a unique filename, added to a starting string or not
public func uniqueFilename(filename: String = "") -> String {
    let uniqueString = ProcessInfo.processInfo.globallyUniqueString
    return filename + ": " + uniqueString
}
// Mostly Unique but Readable filename based on date and time (only "unique" to nearest second and not during DST changes)
public func uniqueFilename2(filename: String = "") -> String {
    let timenow = DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .medium)
    return filename + ": " + timenow
}
1
Golompse

Super facile Swift 4 1-liner:

fileName = "MyFileName_" + UUID().uuidString

ou

fileName = "MyFileName_" + ProcessInfo().globallyUniqueString
1
drewster

Swift 4.1. Passez juste votre nom d’extension de fichier et la fonction retournera un nom de fichier unique.

func uniqueFileNameWithExtention(fileExtension: String) -> String {
        let uniqueString: String = ProcessInfo.processInfo.globallyUniqueString
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMddhhmmsss"
        let dateString: String = formatter.string(from: Date())
        let uniqueName: String = "\(uniqueString)_\(dateString)"
        if fileExtension.length > 0 {
            let fileName: String = "\(uniqueName).\(fileExtension)"
            return fileName
        }

        return uniqueName
    }
0
GSK