OK, lots of comments there, let's try and put something together, because I need the practise and might maybe earn some points [update: didn't :(].
I'm fairly new to 'modern C++' so please take it as you find it. Might need as late as C++17, I haven't checked that too carefully. Any critique more than welcome but I would prefer to edit my own post. And please bear in mind when reading this that what the OP actually wants to do is read his bytes from a file. Thx.
Update: Tweaked to handle the case where the the file size changes between the call to stat()
and the call to fread()
as per @Deduplicator's comment below ... and subsequently replaced fread
with std::ifstream
, I think we're there now.
#include <string>
#include <vector>
#include <optional>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
using optional_vector_of_char = std::optional <std::vector <char>>;
// Read file into a std::optional <std::vector <char>>.
// Now handles the file size changing when we're not looking.
optional_vector_of_char SmarterReadFileIntoVector (std::string filename)
{
for ( ; ; )
{
struct stat stat_buf;
int err = stat (filename.c_str (), &stat_buf);
if (err)
{
// handle the error
return optional_vector_of_char (); // or maybe throw an exception
}
size_t filesize = stat_buf.st_size;
std::ifstream fs;
fs.open (filename, std::ios_base::in | std::ios_base::binary);
if (!fs.is_open ())
{
// handle the error
return optional_vector_of_char ();
}
optional_vector_of_char v (filesize + 1);
std::vector <char>& vecref = v.value ();
fs.read (vecref.data (), filesize + 1);
if (fs.rdstate () & std::ifstream::failbit)
{
// handle the error
return optional_vector_of_char ();
}
size_t bytes_read = fs.gcount ();
if (bytes_read <= filesize) // file same size or shrunk, this code handles both
{
vecref.resize (bytes_read);
vecref.shrink_to_fit ();
return v; // RVO
}
// File has grown, go round again
}
}
int main ()
{
optional_vector_of_char v = SmarterReadFileIntoVector ("abcde");
std::cout << std::boolalpha << v.has_value () << std::endl;
}
Live demo. No actual file available to read in of course, so...
Also: Have you considered writing your own simple container that maps a view of the file? Just a thought.