J'essaie de lire dans un fichier XML de 24 Go en C, mais cela ne fonctionnera pas. J'imprime la position actuelle en utilisant ftell() comme je l'ai lu, mais une fois qu'il est arrivé à un nombre suffisant, il revient à un petit nombre et recommence, ne recevant même pas 20% du fichier. Je suppose que c'est un problème avec la plage de la variable qui est utilisée pour stocker la position (long), qui peut aller jusqu'à environ 4.000.000.000 selon http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.80).aspx, alors que mon fichier est de 25 000 000 000 octets en taille. Un long long devrait fonctionner, mais comment pourrais-je changer ce que mon compilateur (Cygwin/mingw32) utilise ou obtenir pour avoir fopen64?J'effectue des opérations de fichiers avec des adresses 64 bits en C + MinGW32
Répondre
La fonction retourne ftell()
typiquement un unsigned long
, qui va seulement jusqu'à 2 octets (4 GB) sur les systèmes 32 bits. Vous ne pouvez donc pas obtenir le décalage de fichier pour un fichier de 24 Go pour entrer dans un long
32 bits.
Vous pouvez avoir la fonction ftell64()
disponible, ou la fonction standard fgetpos()
peut vous renvoyer un décalage plus important.
Je n'ai pas ftell64(), et fgetpos() renvoie la même chose que ftell() – zacaj
Vous pouvez essayer d'utiliser les fonctions de fichier fournies par le système d'exploitation CreateFile and ReadFile. Selon le sujet File Pointers, la position est stockée en tant que valeur 64 bits.
Sauf si vous pouvez utiliser une méthode 64 bits comme suggéré par Loadmaster, je pense que vous devrez casser le fichier.
This resource semble suggérer qu'il est possible d'utiliser _telli64(). Je ne peux pas tester cela, car je n'utilise pas mingw.
Je ne connais aucun moyen de le faire dans un fichier, un peu un hack mais si le fractionnement du fichier n'est pas une option réelle, vous pouvez écrire quelques fonctions qui divisent le fichier, celui qui utilise ftell() pour se déplacer dans le fichier et échanger ftell() vers un nouveau fichier lorsqu'il atteint le point de partage, puis un autre qui réassemble les fichiers avant de quitter. Une approche absolument bâclée, mais si aucune meilleure solution n'apparaît, cela pourrait être un moyen de faire le travail.
Même si ftell() dans la bibliothèque Microsoft C renvoie une valeur 32 bits et renvoie donc de toute évidence des valeurs erronées une fois que vous avez atteint 2 Go, la lecture du fichier devrait fonctionner correctement. Ou avez-vous besoin de chercher dans le fichier, aussi? Pour cela, vous avez besoin de _ftelli64() et _fseeki64().
Notez que contrairement à certains systèmes Unix, vous n'avez besoin d'aucun drapeau spécial lors de l'ouverture du fichier pour indiquer qu'il est dans un "mode 64 bits". L'API Win32 sous-jacente gère très bien les fichiers volumineux.
J'ai trouvé la réponse. Au lieu d'utiliser fopen, fseek, fread, fwrite ... J'utilise _open, lseeki64, read, write. Et je suis capable d'écrire et de chercher dans des fichiers> 4Go. Edit: Il semble que ces dernières fonctions sont environ 6 fois plus lentes que les précédentes. Je vais donner la prime à quiconque peut l'expliquer.
Edit: Oh, j'ai appris ici que read() et les amis ne sont pas tamponnés. What is the difference between read() and fread()?
wow, un fichier XML de 24 Go. – Malfist
Son wikipedia (le tout) – zacaj
Par curiosité, pourquoi? –