std::istream::read în C++

Citește sau scrie un număr exact de octeți: read și write, pentru fișiere binare.

Sintaxă
std::istream& read(char* destinatie, std::streamsize n);
std::ostream& write(const char* sursa, std::streamsize n);
std::streamsize gcount() const;

Ce face std::istream::read

>> și << lucrează cu text: numărul 1000 devine caracterele 1, 0, 0, 0. write copiază octeții din memorie exact cum sunt, iar read îi citește înapoi. Așa se lucrează cu fișiere binare (imagini, date salvate compact).

Ambele primesc un pointer char* și un număr de octeți. Pentru alte tipuri se folosește reinterpret_cast<char*>(&variabila). Fișierul se deschide cu std::ios::binary, ca sistemul să nu modifice caracterele de rând nou.

După read, gcount() spune câți octeți s-au citit efectiv (pot fi mai puțini la finalul fișierului).

Parametri

Parametru Descriere
destinatie / sursa Zona de memorie în care se citește sau din care se scrie.
n Numărul de octeți.

Ce returnează

Fluxul. La read, dacă nu au fost n octeți, fluxul intră în starea eof și fail.

Exemple

Exemplul 1: Salvarea și încărcarea unui tablou de numere

#include <fstream>
#include <iostream>

int main() {
    int note[] = {9, 7, 10, 8};
    {
        std::ofstream out("note.bin", std::ios::binary);
        out.write(reinterpret_cast<const char*>(note), sizeof(note));
    }

    int citite[4] = {};
    std::ifstream in("note.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(citite), sizeof(citite));
    std::cout << "Octeți citiți: " << in.gcount() << '\n';
    for (int n : citite) {
        std::cout << n << ' ';
    }
    std::cout << '\n';
}

Rezultat

Octeți citiți: 16
9 7 10 8

Exemplul 2: Citirea pe bucăți

Ultima bucată are doar 2 octeți; gcount() arată câți au venit.

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ofstream("mesaj.txt", std::ios::binary) << "Salut, Cluj!";

    std::ifstream in("mesaj.txt", std::ios::binary);
    char bucata[5];
    while (in.read(bucata, sizeof(bucata)) || in.gcount() > 0) {
        std::cout << '[' << std::string(bucata, static_cast<std::size_t>(in.gcount())) << "]\n";
    }
}

Rezultat

[Salut]
[, Clu]
[j!]

Greșeli frecvente

  • Scrii cu write un obiect care conține pointeri sau un std::string: în fișier ajunge adresa, nu textul. Citit înapoi, obiectul este invalid.
  • Fișierele binare scrise pe un calculator pot avea altă ordine a octeților (endianness) sau alte mărimi ale tipurilor pe altă platformă.
  • Uiți std::ios::binary pe Windows: octeții \n sunt transformați în \r\n și datele se strică.

Comenzi înrudite

  • std::ofstream: Creează sau deschide un fișier pentru scriere și scrie în el la fel ca în std::cout.
  • std::ifstream: Deschide un fișier pentru citire și îl citește la fel ca pe std::cin.
  • std::istream::seekg: Mută poziția de citire în flux (seekg) și arată poziția curentă (tellg).
  • std::memcpy: Copiază n octeți dintr-o zonă de memorie în alta; memmove permite zone suprapuse.