11
votes

Un meilleur moyen de déterminer la longueur d'un std :: istream?

Y a-t-il un meilleur moyen de déterminer la longueur d'un STD :: istream que ce qui suit:

std::istream* pcStream = GetSomeStream();
pcStream->seekg(0, ios::end);
unsigned int uiLength = pcStream->tellg();


2 commentaires

Une API que j'utilise nécessite la taille des données que je le passe. Il utilise un tampon de caractère brut et continue de le traiter jusqu'à ce qu'il atteigne la fin du tampon.


Vous pouvez utiliser un stat () dans le fichier. Cependant, ce n'est pas plus rapide que de rechercher à la fin et de la recherche au début avant de lire le contenu ... c'est la mise en œuvre de la manière dont les descripteurs de fichiers sont mis en œuvre. Bien sûr, stat () n'est pas C ++ et il nécessite un nom de fichier ...


4 Réponses :


11
votes

Le «meilleur» moyen est d'éviter de nécessiter la longueur :)

  • Tous les flux ne sont pas recherchés (par exemple, imaginez un Istream sur une prise réseau)
  • Le type de retour de TellG () n'est pas nécessairement numérique (la seule exigence est qu'elle puisse être transmise à la recherche () pour revenir à la même position)
  • Même s'il est numérique, ce n'est pas nécessairement un certain nombre d'octets. Par exemple, il pourrait s'agir d'une valeur "magique" sens "à la fin"
  • pour les FRStreams, des problèmes tels que le cas et la conversion à la ligne de ligne peuvent visser les choses

2 commentaires

Je me rends compte que l'attente d'une longueur soit toujours disponible est un peu limitée au type de ruisseaux à utiliser, heureusement, il est très peu probable que j'utilise autre chose, puis ifstreams et mes propres implémentations Migstream et Zipstream.


On dirait que le type de retour de Tellg () est toujours numérique, basé sur un contrainte de STD :: Streampos .



-2
votes

Avez-vous envisagé de garder une trace de la taille en utilisant Istream :: Gcount ()?


1 commentaires

J'ai besoin de la taille de l'attribution du tampon à laquelle les données seront copiées - je suppose que je pouvais allouer un montant initial et realloc par la suite, mais je suis un peu inquiet de la fragmentation (travaillant dans un environnement MEM limité).



-1
votes

Il y avait une sorte de flux qui ne pouvait pas avoir de longueur en appelant tellg () . Dans le cas de, tellg () peut renvoyer -1 .

Vous pouvez obtenir une longueur de flux en préparant suffisamment de tampon de taille. J'ai découvert comment avoir une longueur en regardant dans flux :: lecture fonction. xxx

ci-dessus, len est une taille de données réelle dans istream .


1 commentaires

Je vais ajouter que cela est utile si vous avez débogué. Ce n'est pas idéal pour le code de production, etc., mais si vous avez un flux qui n'obéira pas à la logique, vous pouvez jeter un coup d'œil sur celui-ci et déterminer ce que vous faites mal ...



-2
votes

Pour obtenir la longueur / la taille actuelle d'une vapeur, je le fais:

auto size = strlen(currentStream.str().c_str());


0 commentaires