Comment obtenir correctement la taille du fichier et le convertir en Mo, Go en Cocoa?

Duplication possible:
Classe ObjC / Cocoa pour convertir la taille en chaîne lisible par l’homme?

Je suis nouveau au cacao. J’essaie d’obtenir la taille des fichiers de dossiers correctement. Et l’afficher en Mo si moins de 1 Go, ou en Go.

La façon dont je veux qu’elle soit affichée est arrondie à un chiffre après le point.

Exemple 5.5 Mo si c’est plus que 1000> 1.1 Go

J’essaie d’utiliser ceci

unsigned long long size= ([[[NSFileManager defaultManager] atsortingbutesOfItemAtPath:fullPath error:nil] fileSize]); 

Mais je ne peux pas convertir correctement le nombre et l’afficher comme je le souhaite.

Merci.

Pour convertir la taille du fichier en Mo, utilisez la fonction ci-dessous

 - (id)transformedValue:(id)value { double convertedValue = [value doubleValue]; int multiplyFactor = 0; NSArray *tokens = @[@"bytes",@"KB",@"MB",@"GB",@"TB",@“PB”, @“EB”, @“ZB”, @“YB”]; while (convertedValue > 1024) { convertedValue /= 1024; multiplyFactor++; } return [NSSsortingng ssortingngWithFormat:@"%4.2f %@",convertedValue, tokens[multiplyFactor]]; } 

MODIFIER:

Vous pouvez également utiliser la classe NSByteCountFormatter . Disponible dans iOS 6.0 / OS X v10.8 et versions ultérieures.

 [NSByteCountFormatter ssortingngFromByteCount:1999 countStyle:NSByteCountFormatterCountStyleFile]; 

Vous pouvez utiliser NSByteCountFormatterCountStyleFile , NSByteCountFormatterCountStyleMemory , NSByteCountFormatterCountStyleDecimal ou NSByteCountFormatterCountStyleBinary dans countStyle.

NSByteCountFormatterCountStyleFile : Spécifie l’affichage du nombre d’octets de fichiers ou de stockage. Le comportement réel pour cela est spécifique à la plate-forme; sous OS X 10.8, cela utilise le style décimal, mais cela peut changer avec le temps.

NSByteCountFormatterCountStyleMemory : Spécifie l’affichage du nombre d’octets de mémoire. Le comportement réel pour cela est spécifique à la plate-forme; sous OS X 10.8, cela utilise le style binary, mais cela peut changer avec le temps.

NSByteCountFormatterCountStyleDecimal : spécifie le nombre d’octets de la base de connaissances explicitement, 1000 octets sont affichés comme 1 Ko

NSByteCountFormatterCountStyleBinary : spécifie le nombre d’octets de la base de connaissances explicitement, 1024 octets sont affichés comme 1 Ko

Si vous ciblez OS X 10.8 ou iOS 6, vous pouvez utiliser NSByteCountFormatter .

Je voudrais écrire votre exemple comme ceci:

  NSError *error = nil; NSDictionary *atsortingbs = [[NSFileManager defaultManager] atsortingbutesOfItemAtPath:path error:&error]; if (atsortingbs) { NSSsortingng *ssortingng = [NSByteCountFormatter ssortingngFromByteCount:[atsortingbs fileSize] countStyle:NSByteCountFormatterCountStyleFile]; NSLog(@"%@", ssortingng); } 

Voici un morceau de code de ma bibliothèque. (Je le publie ici sous la licence BSD simplifiée, donc il est là.) Il est assez largement testé, et il fait tout l’arrondi correctement. Ce n’est pas aussi sortingvial que cela puisse paraître. Il donne toujours deux chiffres significatifs, sauf s’il imprime trois chiffres (par exemple, 980 B), auquel cas les trois chiffres sont significatifs.

L’utilisation de ssortingngWithFormat:@"%..something...f" ne fonctionnera pas, car si vous arrondissez 999999 octets à 1000 kilo-octets, vous voulez afficher 1.0 Mo, pas 1000 Ko.

Notez que ce code fait aussi “l’arrondi du banquier” ou “l’arrondi sans biais” ou “l’arrondit à”, selon ce que vous voulez l’appeler. Donc, 1050 devient “1,0 kB”, mais 1150 devient “1,2 ko”. C’est exactement la même manière que printf fait sur mon système et c’est la méthode d’arrondissement généralement préférée pour ce genre de chose.

 #include  #include  #include  #define SIZE_BUFSZ 7 static char const SIZE_PREFIXES[] = "kMGTPEZY"; void format_size(char buf[SIZE_BUFSZ], uint64_t sz) { int pfx = 0; unsigned int m, n, rem, hrem; uint64_t a; if (sz <= 0) { memcpy(buf, "0 B", 3); return; } a = sz; if (a < 1000) { n = a; snprintf(buf, SIZE_BUFSZ, "%u B", n); return; } for (pfx = 0, hrem = 0; ; pfx++) { rem = a % 1000ULL; a = a / 1000ULL; if (!SIZE_PREFIXES[pfx + 1] || a < 1000ULL) break; hrem |= rem; } n = a; if (n < 10) { if (rem >= 950) { buf[0] = '1'; buf[1] = '0'; buf[2] = ' '; buf[3] = SIZE_PREFIXES[pfx]; buf[4] = 'B'; buf[5] = '\0'; return; } else { m = rem / 100; rem = rem % 100; if (rem > 50 || (rem == 50 && ((m & 1) || hrem))) m++; snprintf(buf, SIZE_BUFSZ, "%u.%u %cB", n, m, SIZE_PREFIXES[pfx]); } } else { if (rem > 500 || (rem == 500 && ((n & 1) || hrem))) n++; if (n >= 1000 && SIZE_PREFIXES[pfx + 1]) { buf[0] = '1'; buf[1] = '.'; buf[2] = '0'; buf[3] = ' '; buf[4] = SIZE_PREFIXES[pfx+1]; buf[5] = 'B'; buf[6] = '\0'; } else { snprintf(buf, SIZE_BUFSZ, "%u %cB", n, SIZE_PREFIXES[pfx]); } } } 

Voici les données de test:

 { 0, "0 B" }, { 5, "5 B" }, { 20, "20 B" }, { 100, "100 B" }, { 500, "500 B" }, { 999, "999 B" }, { 1000, "1.0 kB" }, { 1050, "1.0 kB" }, { 1051, "1.1 kB" }, { 2349, "2.3 kB" }, { 2350, "2.4 kB" }, { 9949, "9.9 kB" }, { 9950, "10 kB" }, { 10000, "10 kB" }, { 10500, "10 kB" }, { 10501, "11 kB" }, { 99499, "99 kB" }, { 99500, "100 kB" }, { 999499, "999 kB" }, { 999500, "1.0 MB" }, { 1000000, "1.0 MB" }, { 952500000, "952 MB" }, { 952500001, "953 MB" }, { 1000000000, "1.0 GB" }, { 2300000000000ULL, "2.3 TB" }, { 9700000000000000ULL, "9.7 PB" }