J'ai besoin d'allouer un gros fichier sans mettre à zéro son contenu. Je produis ces étapes fopen => ftruncate => fclose => mmap => (...work...) => munmap
avec des tailles de fichiers énormes (des centaines de gigaoctets). App se bloque sur la résiliation pendant quelques minutes alors que le système essaie de mettre à zéro les octets de fichier - IMHO en raison de l'utilisation ftruncate
.Allouer le fichier sur le disque sans mise à zéro
ftruncate(ofd, 0);
#ifdef HAVE_FALLOCATE
int ret = fallocate(ofd, 0, 0, cache_size);
if (ret == -1) {
printf("Failed to expand file to size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
#elif defined(HAVE_POSIX_FALLOCATE)
int ret = posix_fallocate(ofd, 0, cache_size);
if (ret == -1) {
printf("Failed to expand file to size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
#elif defined(__APPLE__)
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, cache_size, 0};
int ret = fcntl(ofd, F_PREALLOCATE, &store);
if (ret == -1) {
store.fst_flags = F_ALLOCATEALL;
ret = fcntl(ofd, F_PREALLOCATE, &store);
}
if (ret == -1) { // read fcntl docs - must test against -1
printf("Failed to expand file to size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
struct stat sb;
ret = fstat(ofd, &sb);
if (ret != 0) {
printf("Failed to write to file to establish the size.\n");
exit(-1);
}
//ftruncate(ofd, cache_size); <-- [1]
#endif
Il semble qu'il ne fonctionne pas avec la ligne a commenté [1]
. Mais en décommentant cette ligne produit la réduction à zéro de fichier que j'essaye d'éviter. Je me fiche vraiment du contenu de fichier sale avant d'écrire. Je veux juste éviter de raccrocher à la fin de l'application.
SOLUTION:
Selon l » answer@torfo, remplacé tout mon code lié à Apple avec ces quelques lignes:
unsigned long long result_size = cache_size;
int ret = fcntl(ofd, F_SETSIZE, &result_size);
if(ret == -1) {
printf("Failed set size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
Mais ne fonctionne que pour super-utilisateur!
** deleted ** ('ftruncate()' devrait également créer un fichier fragmenté, il semble donc que votre OS/système de fichiers ne supporte pas les fichiers fragmentés) –
Si vous avez besoin de créer un fichier énorme sans le mettre à zéro , juste "ftruncate" sans faire les autres choses que vous faites. Cela créera un fichier fragmenté si votre système de fichiers le supporte. 'fallocate' et les autres appels feront l'inverse, ils préalloueront et mettront à zéro les blocs de disque. Vous courez le risque de manquer d'espace disque lorsque vous écrivez dans un fichier fragmenté, mais vous ne perdez pas de temps à le mettre à zéro. – Art
L'application @Art avec 'ftruncate' se bloque pendant quelques minutes à la fin via' Ctrl + C'. – k06a