C++ ifstream Writing & reading Pool objects in binary mode

Description

C++ ifstream Writing & reading Pool objects in binary mode

#include  <fstream>
#include  <iostream>
#include  <string>
#include  <vector>
#include <fstream>
#include <iomanip>

using  std::string;

class Pool/*  w w  w  . j  a  v  a 2s  .  c  o  m*/
{
private:
  double length {1.0};
  double width {1.0};
  double height {1.0};

public:
  // Constructors
  Pool(double lv, double wv, double hv) : length {lv}, width {wv}, height {hv} {}

  Pool() = default;                                          // Default constructor

  Pool(const Pool& pool)                                     // Copy constructor
    : length {pool.length}, width {pool.width}, height {pool.height} {}

  double volume() const                                   // Calculate the volume
  {
    return length*width*height;
  }

  friend std::ostream& operator<<(std::ostream& stream, const Pool& pool);
  friend std::istream& operator>>(std::istream& in, Pool& pool);

  friend std::ifstream& read(std::ifstream& in, Pool& pool);
  friend std::ofstream& write(std::ofstream& out, Pool& pool);
};

// Stream insertion operator for Pool objects
inline std::ostream&  operator<<(std::ostream& out, const  Pool&  pool)
{
  return out << std::setw(10) << pool.length << ' '
    << std::setw(10) << pool.width << ' '
    << std::setw(10) << pool.height << '\n';
}

// Stream extraction operation for Pool objects
inline std::istream&  operator>>(std::istream& in, Pool&  pool)
{
  return in >> pool.length >> pool.width >> pool.height;
}

// Binary stream input for Pool objects
inline std::ifstream& read(std::ifstream& in, Pool& pool)
{
  in.read(reinterpret_cast<char*>(&pool.length), sizeof(pool.length));
  in.read(reinterpret_cast<char*>(&pool.width), sizeof(pool.width));
  in.read(reinterpret_cast<char*>(&pool.height), sizeof(pool.height));
  return in;
}

// Binary stream output for Pool objects
inline std::ofstream& write(std::ofstream& out, Pool& pool)
{
  out.write(reinterpret_cast<char*>(&pool.length), sizeof(pool.length));
  out.write(reinterpret_cast<char*>(&pool.width), sizeof(pool.width));
  out.write(reinterpret_cast<char*>(&pool.height), sizeof(pool.height));
  return out;
}


int main(){
    try
    {
      std::vector<Pool> pools {Pool {1.0, 2.0, 3.0}, Pool {2.0, 2.0, 3.0},
        Pool {3.0, 2.0, 2.0}, Pool {4.0, 2.0, 3.0},
        Pool {1.0, 4.0, 3.0}, Pool {2.0, 2.0, 4.0}};

      const string filename {"D:\\Example_Data\\pools.bin"};
      std::ofstream out {filename, std::ios::binary};
      if (!out)
        throw std::ios::failure {string {"Failed to open output file "} + filename};

      for (auto& pool : pools)
        write(out, pool);                                  // Write a Pool object
      out.close();                                        // Close the output stream

      std::cout << pools.size() << " Pool objects written to " << filename << std::endl;

      std::ifstream in {filename, std::ios::binary};      // Create a file input stream
      if (!in)                                            // Make sure it's valid
        throw std::ios::failure {string("Failed to open input file ") + filename};

      std::cout << "Reading objects from the file.\n";
      std::vector<Pool> newPools;
      Pool newPool;
      while (true)
      {
        if(!read(in, newPool)) break;
        newPools.push_back(newPool);
      }
      in.close();                                         // Close the input stream
      std::cout << newPools.size() << " objects read from " << filename << ":\n";
      for (auto& pool : newPools)
        std::cout << pool;
    }
    catch (std::exception& ex)
    {
      std::cout << typeid(ex).name() << ": " << ex.what() << std::endl;
    }
}



PreviousNext

Related