2010-10-27 28 views
2

J'ai réduit le problème à la fonction de base suivante qui devrait simplement imprimer le nombre d'octets dans le fichier. Lorsque je l'exécute pour un fichier de 83886080 octets (80 Mo), il imprime le nombre correct. Cependant, pour un fichier de 4815060992 octets (4,48 Go), il imprime 520093696 ce qui est très faible.Sur windows _fseeki64 ne cherche pas à SEEK_END correctement pour les fichiers volumineux

Il semble avoir quelque chose à voir avec le SEEK_END option, car si je mets le pointeur sur 4815060992 octets manuellement (par exemple _fseeki64(fp, (__int64)4815060992, SEEK_SET)_ftelli64 ne retourne la position correcte. donc une solution de contournement serait d'obtenir la taille du fichier approprié sans en utilisant SEEK_END, comment est-ce fait?

Le code est compilé sur un système Windows 32 bits (donc __int64, _iseeki64 et _ftelli64) avec MinGW.

En bref: qu'est-ce que je fais mal ici?

void printbytes(char* filename) 
{ 
    FILE *fp; 
    __int64 n; 
    int result; 

    /* Open file */ 
    fp = fopen(filename, "rb"); 
    if (fp == NULL) 
    { 
    perror("Error: could not open file!\n"); 
    return -1; 
    } 

    /* Find end of file */ 
    result = _fseeki64(fp, (__int64)0, SEEK_END); 
    if (result) 
    { 
    perror("Error: fseek failed!\n"); 
    return result; 
    } 

    /* Get number of bytes */ 
    n = _ftelli64(fp); 

    printf("%I64d\n", n); 

    /* Close file */ 
    fclose(fp); 
} 
+1

Au lieu de simplement imprimer une erreur, imprimez l'erreur que vous avez. – KevinDTimm

+1

'2^32 + 520093696 = 4815060992' Mais ça devrait marcher, vu que votre n est de type' __int64' --- quoi que ce soit :) – pmg

+0

Peut-être aussi un bug dans printf(). –

Répondre

1

désolé de ne pas poster plus tôt, mais j'ai été préoccupé par d'autres projets pendant un certain temps. La solution suivante fonctionne:

__int64 nsamples(char* filename) 
{ 
    int fh; 
    __int64 n; 

    /* Open file */ 
    fh = _open(filename, _O_BINARY); 

    /* Find end of file */ 
    n = _lseeki64(fh, 0, SEEK_END); 

    /* Close file */ 
    _close(fh); 

return n/sizeof(short); 
} 

L'astuce utilisait _open au lieu de fopen pour ouvrir le fichier. Je ne comprends toujours pas exactement pourquoi cela doit être fait, mais au moins cela fonctionne maintenant. Merci à tous pour vos suggestions qui m'ont finalement orienté dans la bonne direction. (il s'agit d'une copie de la réponse à la question connexe numéro 4003405).

1

Sous Windows, vous devriez être en mesure de « s'habituer » et il suffit d'utiliser GetFileSizeEx().

Je vous conseille également de lire le code généré pour voir si c'est peut-être une confusion de 64 bits qui empêche votre code stdio de fonctionner.