Aller à un certain point d'un fichier binaire en C (à l'aide de fseek), puis la lecture à partir de cet emplacement (à l'aide de fread)
Je me demande si c'est la meilleure façon d'aller sur la résolution de mon problème.
Je sais que les valeurs particulières pour les décalages d'un fichier binaire dans lequel les informations que je souhaite est tenu...Ce que je veux faire est de sauter à la décalages et puis lire un certain nombre d'octets, à partir de cet emplacement.
Après à l'aide de google, j'en suis venu à la conclusion que mon meilleur pari est d'utiliser fseek() pour passer à la position de l'offset, puis d'utiliser fread() pour lire un nombre d'octets à partir de cette position.
Ai-je raison de penser cela? Et si oui, comment est préférable d'aller sur le faire? c'est à dire la manière d'intégrer les deux ensemble.
Si je ne suis pas correct, que suggéreriez-vous-je faire à la place?
Merci beaucoup d'avance pour votre aide.
Matt
Modifier:
J'ai suivi un tutoriel sur la fread() et ajusté à la suivante:
`#include <stdio.h>
int main()
{
FILE *f;
char buffer[11];
if (f = fopen("comm_array2.img", "rt"))
{
fread(buffer, 1, 10, f);
buffer[10] = 0;
fclose(f);
printf("first 10 characters of the file:\n%s\n", buffer);
}
return 0;
}`
J'ai donc utilisé le fichier " comm_array2.img' et de lire les 10 premiers caractères du fichier.
Mais ce que je comprends, cela va de début de fichier, je veux aller de quelques-place-dans-fichier (offset)
Est de ce fait plus de sens?
Modifier Le Numéro 2:
Il semble que j'ai été un peu faible, et tout ce qui est nécessaire (il semblerait, d'après une tentative de ma part) c'est que le fseek() avant le fread() que j'ai dans le code ci-dessus, et il cherche à cet emplacement, puis lit à partir de là.
Oui, vous avez raison, mais quelle est votre question ou problème?
Il y a des tutoriels sur le web qui montrent comment les utiliser. En utilisant les termes de recherche "fseek fread C tutoriel", il devrait être facile à trouver. Avez-vous déjà travaillé par le biais de tout?
Regardez en haut de la
pread()
appel système. Le reproduire à l'aide de flux au lieu de descripteurs de fichiers. Peut-être que vous écrivez vous-même une fonction telle que: ssize_t fpread(char *buffer, size_t nbytes, size_t offset, FILE *fp);
.Si votre plate-forme prend en charge, vous pouvez utiliser
pread()
au lieu de cela, ce qui ne les deux opérations à la fois.OriginalL'auteur user1291631 | 2012-03-25
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez le flux de fichiers au lieu de les descripteurs de fichier, alors vous pouvez écrire vous-même un (simple) fonction analogue à la POSIX
pread()
appel système.Vous pouvez facilement le reproduire à l'aide de flux au lieu de descripteurs de fichier1. Peut-être que vous devez écrire vous-même une fonction comme ceci (qui est un peu différent de l'interface de celui que j'ai suggéré dans un commentaire):
C'est un compromis raisonnable entre les conventions de
pread()
etfread()
.Puisque vous n'avez pas dit combien d'octets à lire, je vais supposer 100 à chaque fois. Je suis en supposant que les variables cibles (tampons) sont
buffer1
etbuffer2
, et qu'ils sont tous les deux assez grand.Le retour est le nombre d'unités complètes de 100 octets; 1 (tout) ou 0 (quelque chose est allé de travers).
Il y a d'autres façons d'écrire ce code:
Ce lit 100 octets à chaque fois; le test permet de s'assurer que vous avez obtenu tous les 100 d'entre eux, comme prévu. Si vous capturez la valeur de retour dans ce deuxième exemple, vous pouvez savoir combien de données vous avez obtenu. Il serait très surprenant que la première lecture a réussi et le second a échoué; un autre programme (ou thread) aurait dû tronquer le fichier entre les deux appels à
fpread()
, mais plus drôle de choses ont été connus pour se produire.1 L'émulation de ne pas être parfait; le
pread()
appel garantit l'atomicité que la combinaison defseek()
etfread()
ne fournira pas. Mais ce sera rarement un problème dans la pratique, sauf si vous avez plusieurs processus ou threads simultanément mise à jour du fichier pendant que vous êtes en train de les positionner et de les lire sur elle.Sorte de...de Votre commentaire mentionne le nom de fichier, mais ni
fread()
nifseek()
travaille avec des noms de fichiers; c'est-àfopen()
'emploi. Lefpread()
est une fonction presque baisse-dans le remplacement pour lesfseek()
etfread()
appels. Clairement, si vous voulez prendre un nom de fichier, vous devezfopen()
et (probablement)fclose()
le fichier à l'intérieur de la fonction, et vous ne serez pas en passant lafp
paramètre. Vous auriez probablement mettre le nom de fichier comme premier argument. Vous pouvez utiliser"rb"
pour ouvrir le fichier binaire pour la lecture; il n'a pas d'importance si le b est-il sur Unix, mais sur d'autres plates-formes, il n'.Ah oui, mes excuses, je voulais dire passer ce serait 'fp' (c'est à dire ce qui est normalement renvoyé lorsque vous utilisez fopen() comme je le comprends) Cependant, à partir de votre commentaire, je vois que je ne m'en fait passer le 'fp' paramètre?
Le code ci prévoit la
FILE *
; je vous attends pour passer le flux de fichier. (J'ai été confus/trompés par votre premier commentaire.) Vous écrire une fonction pour ouvrir, de position, de lire, de fermer un nom de fichier, puis vous passerez un nom de fichier au lieu d'un flux de fichier. Mais, si vous allez lire plus d'une section du fichier à un moment, je ne le recommanderais pas;fopen()
est relativement lente de la fonction, et doit être appelé plus souvent que nécessaire. Donc, compte tenu de votre commentaire d'origine signifiait flux de fichier à la place du nom de fichier, alors oui: vous pouvez utiliserfpread()
comme vous le vouliez.Ok, merci beaucoup pour votre aide et éclaircissements. Une dernière chose, de sorte que je peux parfaitement comprendre votre fonction que vous avez créé, quelle serait la syntaxe de l'appel de la fonction? Par exemple, la lecture à partir de l'offset 732, puis à nouveau à partir de l'offset 432 (les deux étant à partir du début du fichier) et filestream appelé "f". Je m'excuse si cela semble être une question simple, mais je veux m'assurer que je comprends totalement. Merci encore pour votre temps, c'est très apprécié.
OriginalL'auteur Jonathan Leffler
Il dépend fréquemment de la distance entre les pièces qui vous intéressent. Si vous n'avez qu'à sauter au-dessus/en ignorant les quelques octets entre les parties qui vous intéressent, il est souvent plus facile à lire que les données et ignorer ce que vous lisez, plutôt que d'utiliser
fseek
de passer au-delà. D'une manière typique pour ce faire est de définir une structure qui détient à la fois les données dont vous vous souciez, et placez-les titulaires pour ceux qui ne vous intéressent pas, lire dans la structure, puis il suffit d'utiliser les pièces dont vous vous souciez:Si il y a une grande distance entre les pièces dont vous vous souciez, cependant, les chances sont que votre idée de départ, à l'aide de
fseek
pour obtenir les éléments de la matière sera plus simple.OriginalL'auteur Jerry Coffin
Votre théorie, c'est correct. Ouvrir, chercher, lire, fermer.
Créer une structure pour les données que vous souhaitez lire et de passer un pointeur à lire() de la structure de la mémoire allouée. Vous aurez probablement besoin de #pragma pack(1) ou similaire sur la structure pour empêcher le désalignement des problèmes.
OriginalL'auteur Java42