Is this approach safe?

G

Giff

Hi all,

I am filling up a class by reading a binary file.
I have a Read(std::string& name) method that opens the file and reads
the inside.
The first few lines of the file contain some text describing the size of
the data that follows; imagine that the file contains some images and
this first line tells the size of the images and their number.

Having this info, what I do is to call a function Init() that allocates
all the necessary memory to be filled up with the raw data coming from
the file. In this way, being always inside the method Read(), I start to
read the actual values only after that the function Init() has returned.

The stream remains open during the call to Init(). I was now thinking:
what if for some reason, when the function returns, the stream has been
closed and the loading of the values fails miserably?

How would you suggest to tackle this problem in a safer way? One way
would be to have two different files: the first with the info about the
data contained in the second one. I am sure there is a better way though.

Thanks.
 
V

Victor Bazarov

Giff said:
I am filling up a class by reading a binary file.
I have a Read(std::string& name) method that opens the file and reads
the inside.
The first few lines of the file contain some text describing the size
of the data that follows; imagine that the file contains some images
and this first line tells the size of the images and their number.

Having this info, what I do is to call a function Init() that
allocates all the necessary memory to be filled up with the raw data
coming from the file. In this way, being always inside the method
Read(), I start to read the actual values only after that the
function Init() has returned.
The stream remains open during the call to Init(). I was now thinking:
what if for some reason, when the function returns, the stream has
been closed and the loading of the values fails miserably?

Closing of a stream is an operation on the stream variable. *Whad* can
close *your* stream if *you're* holding the reins? *What* reason can it
possibly be?

Now, if you have been reading from a removable storage (like a CD or
a floppy disk) and then the user pushes the "eject" button on the front
of the computer during reading, this usually leads to _an_exceptional_
situation. Handling those is what *C++ exceptions* are for.
How would you suggest to tackle this problem in a safer way? One way
would be to have two different files: the first with the info about
the data contained in the second one. I am sure there is a better way
though.

If the read operation fails, stop reading, set the "bad state of the
object" flag and return. The caller should verify that the data have
been properly read from the file (stream).

V
 
G

Giff

Victor said:
> Closing of a stream is an operation on the stream variable. *Whad* can
> close *your* stream if *you're* holding the reins? *What* reason can it
> possibly be?


OK, I was thinking that the OS could close the stream in case it would
need to.

> Handling those is what *C++ exceptions* are for.


So, do you think that exception handling is superfluous in my case (I
read from the HD)?

>
> If the read operation fails, stop reading, set the "bad state of the
> object" flag and return. The caller should verify that the data have
> been properly read from the file (stream).


Thanks Victor.
 
V

Victor Bazarov

Giff said:
OK, I was thinking that the OS could close the stream in case it would
need to.

I don't think OS is aware of *your* streams. The underlying file can
of course be deleted, for example, or the admin can change the access
rights and so on, but dealing with those things is really in the realm
of the OS (rather than the language)...
So, do you think that exception handling is superfluous in my case (I
read from the HD)?

No, I actually think that you should essentially throw some I/O-specific
exception if, beyond any normal functioning, your program fails to read
from the file it just opened for reading (and began reading successfully)
and should be able to finish.

Now, there are degrees of problems your I/O code can encounter and you
need to decide at what point to consider it normal "error handling" and
an what point to just thrown "hands in the air", so to speak, and declare
the situation so unusual that nobody can predict it. For example, if the
file you're given has at least enough bytes to probably contain whatever
you're about to read from it, it's fine, and if it's size is significantly
smaller than what should be there, you can predict errors before trying
to read from that file. If the OS closes the file your own program deemed
OK beforehand, during your reading of the file, it's an exceptional case,
and not "normal" or "expected" (if any error can be called that).

V
 
J

Jim Langston

Giff said:
Hi all,

I am filling up a class by reading a binary file.
I have a Read(std::string& name) method that opens the file and reads the
inside.
The first few lines of the file contain some text describing the size of
the data that follows; imagine that the file contains some images and this
first line tells the size of the images and their number.

Having this info, what I do is to call a function Init() that allocates
all the necessary memory to be filled up with the raw data coming from the
file. In this way, being always inside the method Read(), I start to read
the actual values only after that the function Init() has returned.

The stream remains open during the call to Init(). I was now thinking:
what if for some reason, when the function returns, the stream has been
closed and the loading of the values fails miserably?

How would you suggest to tackle this problem in a safer way? One way would
be to have two different files: the first with the info about the data
contained in the second one. I am sure there is a better way though.

As Victor says correctly, this would be a case I would throw an exception.
If your funciton is given a filename and is expected to read its contents
and return them somehow, if it can not then this is an error. It *should*
work. If it doesn't then what can you expect the code that called Read to
do? Not much. So throw. Whatever called Read then can decide to catch the
except and try something different, or let it proprate up til something
catches it or the program terminates.

If it is not real iimportant that this file is read, then whatever calls
read can catch it and do something else. If it is extremely important,
whatever calls it can still catch it if it wants and display a diagnostis
message and throw itself.

It should throw for a number of reasons. 1. It can't open the file 2. The
file closes before it's finished reading. 3. The data length is not correct
You should probably give the reason the read failed in what you throw, some
time of message or constant.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top