0Pricing
C++ Academy · Lekcja

Binarne wejście-wyjście plików

Odczytuj i zapisuj surowe bajty

Binarne wejście-wyjście plików to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.

Tekst a dane binarne

Tryb tekstowy zapisuje znaki czytelne dla człowieka, natomiast tryb binarny zapisuje surowe bajty obiektów dokładnie w postaci przechowywanej w pamięci. Plik należy otworzyć za pomocą std::ios::binary.

#include <iostream>
#include <fstream>

int main() {
    int value = 12345;
    std::ofstream out("v.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&value), sizeof(value));
    std::cout << "wrote " << sizeof(value) << " bytes\n";
    return 0;
}

write przyjmuje bajty

write(ptr, n) zapisuje n surowych bajtów spod adresu ptr. Adres obiektu należy rzutować na const char*.

#include <iostream>
#include <fstream>

int main() {
    double d = 3.14;
    std::ofstream out("d.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&d), sizeof(d));
    out.close();
    std::cout << "saved a double\n";
    return 0;
}

read odtwarza bajty

read(ptr, n) wczytuje n bajtów do obiektu znajdującego się pod adresem ptr, odwracając operację zapisu binarnego.

#include <iostream>
#include <fstream>

int main() {
    int original = 777;
    std::ofstream("i.bin", std::ios::binary).write(reinterpret_cast<const char*>(&original), sizeof(original));
    int loaded = 0;
    std::ifstream in("i.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(&loaded), sizeof(loaded));
    std::cout << loaded << '\n';
    return 0;
}

Zapisywanie struktury POD

Struktury zawierające zwykłe dane (bez wskaźników i ze składowymi o stałym rozmiarze) można zapisać i ponownie wczytać jako jeden blok bajtów.

#include <iostream>
#include <fstream>

struct Record { int id; double balance; };

int main() {
    Record r{1, 99.5};
    std::ofstream out("rec.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&r), sizeof(r));
    std::cout << "struct saved\n";
    return 0;
}

Ponowne odczytywanie struktury

Odczyt odtwarza całą strukturę w jednym wywołaniu read.

#include <iostream>
#include <fstream>

struct Record { int id; double balance; };

int main() {
    Record w{42, 250.0};
    std::ofstream("r2.bin", std::ios::binary).write(reinterpret_cast<const char*>(&w), sizeof(w));
    Record r{};
    std::ifstream in("r2.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(&r), sizeof(r));
    std::cout << r.id << ' ' << r.balance << '\n';
    return 0;
}

Zapisywanie tablicy

Całą tablicę można zapisać jednym wywołaniem, przekazując jej całkowity rozmiar w bajtach.

#include <iostream>
#include <fstream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    std::ofstream out("arr.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(arr), sizeof(arr));
    std::cout << "wrote " << sizeof(arr) << " bytes\n";
    return 0;
}

Ponowne odczytywanie tablicy

Należy odczytać tę samą liczbę bajtów do tablicy o takim samym rozmiarze.

#include <iostream>
#include <fstream>

int main() {
    int src[5] = {10, 20, 30, 40, 50};
    std::ofstream("a2.bin", std::ios::binary).write(reinterpret_cast<const char*>(src), sizeof(src));
    int dst[5] = {};
    std::ifstream in("a2.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(dst), sizeof(dst));
    for (int x : dst) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Przemieszczanie pozycji

seekg (get) i seekp (put) przesuwają pozycję odczytu lub zapisu, umożliwiając swobodny dostęp do danych w pliku.

#include <iostream>
#include <fstream>

int main() {
    int data[3] = {100, 200, 300};
    std::ofstream("seek.bin", std::ios::binary).write(reinterpret_cast<const char*>(data), sizeof(data));
    std::ifstream in("seek.bin", std::ios::binary);
    in.seekg(sizeof(int)); // skip to second int
    int second; in.read(reinterpret_cast<char*>(&second), sizeof(second));
    std::cout << second << '\n';
    return 0;
}

Odczytywanie pozycji

tellg i tellp zwracają bieżącą pozycję, co jest przydatne do określania rozmiaru pliku lub przesunięć.

#include <iostream>
#include <fstream>

int main() {
    int data[4] = {1, 2, 3, 4};
    std::ofstream("tell.bin", std::ios::binary).write(reinterpret_cast<const char*>(data), sizeof(data));
    std::ifstream in("tell.bin", std::ios::binary);
    in.seekg(0, std::ios::end);
    std::cout << "file size: " << in.tellg() << " bytes\n";
    return 0;
}

Dlaczego nie wskaźniki

Nigdy nie należy zapisywać binarnie obiektów zawierających wskaźniki ani std::string: zapisany zostanie adres wskaźnika, a nie dane, na które wskazuje. Zamiast tego należy serializować zawartość.

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

int main() {
    std::string s = "hello";
    std::ofstream out("str.bin", std::ios::binary);
    std::size_t len = s.size();
    out.write(reinterpret_cast<const char*>(&len), sizeof(len));
    out.write(s.data(), len); // write the chars, not the object
    std::cout << "serialized " << len << " chars\n";
    return 0;
}

Uwagi dotyczące przenośności

Układ danych binarnych zależy od kolejności bajtów i rozmiarów typów. Pliki zapisane na jednej platformie mogą nie zostać poprawnie odczytane na innej, dlatego na potrzeby współdzielenia należy zdefiniować stały format.

#include <iostream>
#include <cstdint>

int main() {
    std::int32_t fixed = 1; // fixed-width type for portability
    std::cout << "sizeof int32_t = " << sizeof(fixed) << '\n';
    return 0;
}

Szybki test

Proszę sprawdzić swoją wiedzę na temat binarnego wejścia i wyjścia.

Podsumowanie

Poznali Państwo binarne wejście i wyjście plikowe:

  • plik należy otworzyć za pomocą std::ios::binary, a następnie używać write i read z reinterpret_cast<char*>
  • seekg, seekp, tellg i tellp zapewniają swobodny dostęp do danych
  • nie należy bezpośrednio zapisywać wskaźników ani łańcuchów znaków; trzeba serializować ich zawartość i pamiętać o kolejności bajtów

Następnie nauczą się Państwo sprawdzać stan strumienia i obsługiwać błędy.

Często zadawane pytania

Czy lekcja „Binarne wejście-wyjście plików” jest bezpłatna?

Tak — pełny tekst „Binarne wejście-wyjście plików” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Binarne wejście-wyjście plików”?

Odczytuj i zapisuj surowe bajty Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C++ Academy?

Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Binarne wejście-wyjście plików”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?

Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Odczytywanie plików za pomocą ifstream
  2. Zapisywanie plików za pomocą ofstream
  3. Binarne wejście-wyjście plików
  4. Obsługa błędów i stan
← Powrót do C++ Academy