Data Access Layer :
Data access layer (DAL) Provides simplified access to data stored in persisted storage of some kind. DAL may provide a reference to an object in terms of oops.This allows the client (or user) modules to be created with a higher level of abstraction. Achieving data abstraction for writing data to files and reading data from files is a big challenge ahead of us.Let us see how we can provide abstraction for reading and writing files in c++. Best way of encapsulation of data is done through classes.
DataWriter class:
DataWriter class provides a way to write any type of data into a file.1. Create DataWriter object.
2. Call WriteData method.
3. Close the writer.
source code :
class DataWriter
{
public:
DataWriter()
{
m_in = nullptr;
m_error = 0;
}
DataWriter(const wchar_t* fileName, const wchar_t* fileMode)
{
OpenWriter(fileName, fileMode);
}
~DataWriter()
{
CloseWriter();
}
inline void OpenWriter(const wchar_t* fileName, const wchar_t* fileMode)
{
if(!fileName)
throw std::exception("file name cant be empty");
if(!fileMode)
throw std::exception("file mode cant be empty");
m_error = _wfopen_s(&m_in, fileName, fileMode);
if(m_error == EINVAL)
{
CloseWriter();
throw std::exception("error opening file");
}
}
inline void CloseWriter()
{
if(m_in)
{
m_error = _fclose_nolock(m_in);
m_in = nullptr;
}
}
template <typename T> inline void WriteData(T* ptr, long long lengthInBytes)
{
m_error = _fwrite_nolock(ptr, lengthInBytes, 1, in);
if(m_error != lengthInBytes)
{
CloseWriter();
throw std::exception("error writing to file");
}
}
private:
FILE* m_in;
errno_t m_error;
};
DataReader class:
DataReader class provides a way to read any type of data from a file.1. Create DataReader object.
2. Call ReadData method.
3. Close the reader.
source code :
class DataReader
{
public:
DataReader()
{
m_in = nullptr;
m_error = 0;
}
DataReader(const wchar_t* fileName, const wchar_t* fileMode)
{
OpenReader(fileName, fileMode);
}
~DataReader()
{
CloseReader();
}
inline void OpenReader(const wchar_t* fileName, const wchar_t* fileMode)
{
if(!fileName)
throw std::exception("file name cant be empty");
if(!fileMode)
throw std::exception("file mode cant be empty");
m_error = _wfopen_s(&m_in, fileName, fileMode);
if(m_error == EINVAL)
{
CloseReader();
throw std::exception("error opening file");
}
}
inline void CloseReader()
{
if(m_in)
{
m_error = _fclose_nolock(m_in);
m_in = nullptr;
}
}
template <typename T> inline void ReadData(T* ptr, long long lengthInBytes)
{
m_error = _fread_nolock(ptr, lengthInBytes, 1, in);
if(m_error != lengthInBytes)
{
CloseReader();
throw std::exception("error writing to file");
}
}
private:
FILE* m_in;
errno_t m_error;
};