8
votes

Lire une partie d'un fichier avec iostreams

puis-je ouvrir un ifstream (ou définir une existante de quelque manière que ce soit) pour lire uniquement une partie d'un fichier? Par exemple, j'aimerais avoir mon ifstream lire un fichier à partir de l'octet 10 à 50. La recherche de la position 0 serait la position 10 en réalité, la lecture de la position passée 40 (50 en réalité) serait constituée dans un EOF , etc. est-ce possible de quelque manière que ce soit?


0 commentaires

3 Réponses :


5
votes

Vous pouvez lire les octets que vous souhaitez dans une chaîne ou une matrice de caractère, vous pouvez utiliser cette chaîne avec une iSTringstream et utiliser cela au lieu de votre ifstream. Exemple: xxx

Si vous devez gérer des fichiers binaires, vous pouvez le faire aussi: xxx


3 commentaires

Il convient de noter que cette solution fonctionnera uniquement avec des fichiers texte.


@Khalednassar: il peut facilement être adapté au travail pour les fichiers binaires. Terminé.


Un problème avec cette approche est que la plage à lire peut être assez grande. Bien sûr, s'il est effectivement formidable, vous voudrez peut-être prendre soin de la plage séparément de toute façon.



2
votes

Vous voudrez peut-être implémenter votre propre classe de lecture de flux (de préférence via une interface ifstream si on existe).


0 commentaires

8
votes

Il peut absolument être fait en implémentant un tampon de filtrage: vous dérivez de std :: streambuf code> et prenez la plage que vous souhaitez exposer et le tampon de flux sous-jacent (puits, un pointeur. ) comme des arguments. Ensuite, vous chercheriez à l'emplacement de départ. Une fonction de sous-flux code> remplaçable () CODE> lirait à partir du tampon de flux sous-jacent dans son tampon jusqu'à ce que cela soit consommé autant de caractères que c'était souhaité. Voici une version quelque peu rugueuse et entièrement non testée:

#include <streambuf>
struct rangebuf: std::streambuf {
    rangebuf(std::streampos start,
                    size_t size,
                    std::streambuf* sbuf):
        size_(size), sbuf_(sbuf)
    {
        sbuf->seekpos(start, std::ios_base::in);
    }
    int underflow() {
        size_t r(this->sbuf_->sgetn(this->buf_,
            std::min<size_t>(sizeof(this->buf_), this->size_));
        this->size -= r;
        this->setg(this->buf_, this->buf_, this->buf_ + r);
        return this->gptr() == this->egptr()
            ? traits_type::eof()
            : traits_type::to_int_type(*this->gptr());
    }
    size_t size_;
    std::streambuf* sbuf_;
};


0 commentaires