Je cherche des éclaircissements sur la façon dont seekg()
et seekp()
fonctionne quand vous écrivez dans un fichier. Disons par exemple que j'avais un fichier comme ça:
offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
Maintenant, je veux ouvrir le fichier et faire quelques recherches pour lire et écrire des valeurs.
fstream file;
file.open("file.txt", fstream::in |fstream::out | fstream::binary);
file.seekp(0, ios::end) // seek to the end of the file
int eofOffset = file.tellp(); // store the offset of the end-of-file, in this case 20
int key = 0;
file.seekg(12, ios::beg); // set the seek cursor to offset 12 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 8
file.seekg(8, ios::beg); // set the seek cursor to offset 8 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 6
Maintenant, je veux écrire à la fin du fichier. Étant donné que la fonction seekg()
déplace uniquement le curseur de recherche, mon curseur seekp()
doit toujours être à la fin du fichier, n'est-ce pas? Alors:
int newKey = 12;
file.write((char *) &newKey, sizeof(int));
devrait faire ressembler mon fichier:
offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
offset 20: 12
Maintenant, qu'arrive-t-il à mon fichier si je choisis de rechercher un décalage et d'écrire sa valeur comme décalage dans la valeur qui vient d'être insérée. Par exemple, je veux que offset 8
Contienne eofOffset = 20
Puisque nous venons d'insérer 12 à ce décalage.
Si je fais:
file.seekp(8, ios::beg);
file.write((char *) &eofOffset, sizeof(int));
réécrit-il correctement mon fichier pour ressembler à ceci:
offset 0: 2
offset 4: 4
offset 8: 20
offset 12: 8
offset 16: 10
offset 20: 12
Veuillez me faire savoir si je fais des erreurs en utilisant les fonctions seekg()
et seekp()
.
Le modèle de classe std::basic_filebuf
Contient une seule position de fichier
§ 27.9.1.1
- La classe basic_filebuf associe à la fois la séquence d'entrée et la séquence de sortie à un fichier.
- Les restrictions sur la lecture et l'écriture d'une séquence contrôlée par un objet de classe basic_filebuf sont les mêmes que pour la lecture et l'écriture avec les FICHIERS de la bibliothèque C standard.
- En particulier:
- Si le fichier n'est pas ouvert pour la lecture, la séquence d'entrée ne peut pas être lue.
- Si le fichier n'est pas ouvert pour l'écriture, la séquence de sortie ne peut pas être écrite.
- ne position de fichier commune est conservée pour la séquence d'entrée et la séquence de sortie.
Cela signifie que lorsque vous utilisez un std::basic_fstream
, Qui par défaut utilise un std::basic_filebuf
, La position du fichier unique est déplacée par les deux seekp()
et seekg()
; à moins que vous n'utilisiez une variable distincte pour stocker l'une des positions afin que vous puissiez ensuite y revenir, vous ne pouvez pas suivre les positions put et get indépendamment.
Les implications du point 2 sont qu'entre les lectures et les écritures sur un fstream
, vous devez soit vider le tampon, soit rechercher la position du fichier lors du passage de la sortie à l'entrée, et vous devez soit être à la fin du fichier, soit rechercher la position du fichier lors du passage de l'entrée à la sortie.
Pour plus de détails sur ces restrictions, voir la section 7.19.5.3/7 de la norme C99 ("La fonction fopen
"), ou 7.21.5.3/7 de C11.