2015-12-21 2 views
4

Il semble y avoir de nombreuses façons de chercher dans C:Quelle est la meilleure façon de rechercher 2GiB passé en C?

  • fseek()
  • fsetpos()
  • fseeko()
  • lseek()

Et beaucoup semblent avoir *64() versions:

  • fseeko64()
  • lseek64()

Pour compliquer les choses beaucoup semblent exiger des définitions de macros (comme _LARGEFILE64_SOURCE ou _GNU_SOURCE) être disponible ou utiliser des versions 64 bits. Quelle est la meilleure façon de garantir des E/S de 64 bits en utilisant ANSI C sous Windows, Linux, Mac, BSD, Solaris, etc. et depuis quand est-ce que chaque système d'exploitation a pris en charge cette fonctionnalité?

+0

meilleur en vitesse, le meilleur de la compatibilité, le meilleur dans la simplicité du code? – chux

+0

@chux Dans l'application je développe la simplicité du code et la compatibilité sont mes principales préoccupations, mais toute réponse serait appréciée. – buggy3

+1

[Puis-je rechercher une position au-delà de 2 Go en C en utilisant la bibliothèque standard?] (Http://stackoverflow.com/q/30657968/995714) –

Répondre

1

code fonctionne a besoin d'employer au moins 1 de la restriction ci-dessous ::

  1. long est de 64 bits +, puis utilisez fseek(). Recherchez uniquement les emplacements auxquels le code a été précédemment attribué en raison de fread(), fgets(), fscanf(), fgets(), et utilisez par conséquent fgetpos(), fsetpos(). C'est le meilleur moyen si le fichier est un fichier texte.

  2. Avoir accès à une recherche 64 bits dépendante de la plate-forme, telle que lseek64().

  3. Plusieurs 32 bits fseek().

  4. Utilisez un code très inefficace avec rewind() et fgetc()/fread().

+0

Je ne suis pas sûr de plusieurs fseek() et fgepos 32 bits()/fsetpos() peut ne pas fonctionner non plus (très probablement les deux types de fonctions de positionnement utilisent le même type pour la position et appellent la même fonction spécifique au système d'exploitation à la fin). Une fonction/syscall spécifique au système d'exploitation est la meilleure solution, bien que clairement non portable. –

+0

@Alexey Frunze 'fgetpos()/fsetpos()' fonctionne aussi bien sur le système 64 bits que sur 32. 'fseek()' passe 4G sur les systèmes 32 bits est plus ténu. Une solution combo comme vous l'avez mentionné est la meilleure, en utilisant des appels standard comme capable. – chux

0

Quelle est la meilleure façon de garantir 64 bits IO en utilisant la norme ANSI C sur Windows, Linux, Mac, BSD, Solaris, etc.

Le plus simple? Compilez votre code en tant qu'exécutable 64 bits. Veillez à utiliser les types appropriés, par ex. size_t est et non et unsigned int - size_t est size_t. Et heureusement, vous avez dépassé ANSI C, car cela fait généralement référence à C89 et ne supporte probablement pas bien les architectures 64 bits.

Et comme implicite dans les commentaires, il n'y a pas de moyen conforme à la norme C pour garantir que vous pouvez facilement dépasser 2Go.Avec un binaire 64 bits, cependant, les E/S compatibles POSIX (open(), read(), write(), etc.) fonctionneraient tous comme size_t/ssize_t utilisé par POSIX IO est 64 bits. POSIX spécifie également fseeko() and ftello(), qui sont compatibles 64 bits.

et depuis quand est-ce que cela a été pris en charge par chaque système d'exploitation?

Voir here pour plus de détails. En gros, "plein" dates de prise en charge 64 bits à environ les temps suivants:

  • Solaris: 1998
  • Linux: 2003
  • de Windows: 2006
  • OS X: 2007
+1

La fonction 'fseek()' définie par la norme C passe 'offset' comme' long', bien que, selon le [modèle de données] (https://en.wikipedia.org/wiki/64-bit_computing#64- bit_data_models) (par exemple Windows utilise LLP64), 'long' ne peut pas être 64 bits; C'est de là que vient la limitation de 2GiB ('LONG_MAX' doit être au moins (2^31) -1). – buggy3

+0

@oopaewem Merci d'avoir signalé cela, mais l'OP vous a demandé le moyen le * plus simple *. Dans ce cas, vous êtes de retour au lien de Lưu Vĩnh Phúc dans son commentaire ci-dessus (qu'il n'y a pas de manière conforme à la norme C): http://stackoverflow.com/questions/30657968/can-i-seek-a- position-beyond-2gb-in-c-using-the-bibliothèque-standard. –

+0

J'ai vu ce lien, et je suppose que mon OP est légèrement trompeur. Par ANSI CI ne signifiait pas que je voulais utiliser exclusivité ANSI C et aucune autre bibliothèque (éventuellement dépendante de la plate-forme), je voulais juste dire que je ne voulais pas utiliser de fonctionnalités C99 ou C11, car Microsoft n'a toujours pas compléter le compilateur C99 (et ils ne prévoient pas de le faire). Cela dit, C11 ne semble pas non plus avoir de moyen standard pour rechercher 2GiB passé sur un modèle de données LLP64, donc c'est un peu discutable. – buggy3