Sur la base de cette question:

Comment lire un fichier binaire dans un vecteur de caractères non signés

Dans la réponse, ils ont:

std::vector<BYTE> readFile(const char* filename)
{
    // open the file:
    std::basic_ifstream<BYTE> file(filename, std::ios::binary);

    // read the data:
    return std::vector<BYTE>((std::istreambuf_iterator<BYTE>(file)),
                              std::istreambuf_iterator<BYTE>());
}

Qui lit le fichier entier dans le vecteur.

Ce que je veux faire, c'est lire (par exemple) 100 octets à la fois dans le vecteur, puis faire des trucs, puis lire les 100 octets suivants dans le vecteur (effacer le vecteur entre). Je ne vois pas comment spécifier la quantité de fichier à lire (c'est-à-dire comment configurer les itérateurs). Est-ce que c'est possible?

J'essaie d'éviter d'avoir à écrire ma propre boucle de code pour copier chaque octet à la fois.

1
code_fodder 23 mai 2018 à 18:08

3 réponses

Meilleure réponse

Vous pouvez utiliser ifstream::read pour cela.

std::vector<BYTE> v(100);
while ( file.read(reinterpret_cast<char*>(v.data()), 100) )
{
   // Find out how many characters were actually read.
   auto count = file.gcount();

   // Use v up to count BTYEs.
}
3
R Sahu 23 mai 2018 à 15:14

Vous pouvez écrire une fonction dans:

void readFile( const std::string &fileName, size_t chunk, std::function<void(const std::vector<BYTE>&)> proc )
{
    std::ifstream f( fileName );
    std::vector<BYTE> v(chunk);
    while( f.read( v.data(), v.size() ) ) {
        v.resize( f.gcount() );
        proc( v );
        v.resize( chunk );
    }
}

Alors l'utilisation est simple:

void process( const std::vector<BYTE> &v ) { ... }

readFile( "foobar", 100, process ); // call process for every 100 bytes of data

Ou vous pouvez utiliser lambda etc. pour le rappel.

1
Slava 23 mai 2018 à 15:24

Ou vous pouvez écrire votre propre fonction pour cela:

template<typename Data>
std::istreambuf_iterator<Data> readChunk(std::istreambuf_iterator<Data>& curr, std::vector<Data>& vec, size_t chunk = 100) {
    for (int i = 0; curr != std::istreambuf_iterator<Data>() && i < chunk; ++i, ++curr) {
        vec.emplace_back(*curr);
    }
    return curr;
}

Et l'utiliser comme:

std::ifstream file("test.cpp");
std::vector<BYTE> v;
std::istreambuf_iterator<BYTE> curr(file);
readChunk<BYTE>(curr, v);

Et vous pouvez à nouveau appeler cette fonction.

0
Mateusz Wojtczak 23 mai 2018 à 16:05