Link to home
Start Free TrialLog in
Avatar of zizi21
zizi21

asked on

file modes wb vs wb+

hi,

i have a file that i am writing and reading. If I open at as wb+, the time to run a file is about 5 seconds and if I left it as wb, the time is 9 seconds.

Is there a difference using wb and wb+ ?

Tks.
Avatar of phoffric
phoffric

Are you doing error handling on every I/O call?

From     http://www.cplusplus.com/reference/clibrary/cstdio/fopen/
w ==   Create an empty file for writing.
w+ == Create an empty file for both reading and writing.
(the b is just binary file).

I am surprised about the time difference if you are only writing. If reading also, then "wb+" should be the only one that works.
Avatar of zizi21

ASKER

I am doing reading and writing and there is a couple of other weird issues too..

when i do wb, this works
p=ftell(fp);      
if(c > p)
{
   f= c - p;
   fseek(fp,f,SEEK_CUR);
}
else if(c< p)
{
     b=p - c;
  fseek(fp,-b,SEEK_CUR);
}

but it doesn't work properly when i do wb+. in order for it to code with wb+, i need to add the extra else..

else
{
     fseek(fp,0,SEEK_CUR);
}

I face this issue on mac..but it seems to work fine (without the else on a linux server..)

Avatar of zizi21

ASKER

that's why I thought, it is a file mode issue..
in this file, i could write a character and then, the next moment, i could also read the character that i have just written.
>> I am doing reading and writing
>> when i do wb, this works
>> write a character and then, the next moment, i could also read the character that i have just written.

How does your read work if "wb"? Doesn't that give an I/O error since you are opening the file for write-only?
Avatar of zizi21

ASKER

it doesn't give any error thats why it is weird..
I'll try to see for myself (unless you have a small program to illustrate the problem).

>> p=ftell(fp);      
>> if(c > p)
>> else if(c< p)
>> doesn't work properly when i do wb+.

1) In this if..else, what did you want to do when c==p ?
2) What is the operation you do (read or write) before the ftell?
3) What is the operation you do (read or write) after the if..else?
4) Please explain what does not work properly? (If you already explained it, please elaborate. Thanks.)
Avatar of zizi21

ASKER

sorry the program is really huge..my assignment....i am not suppose to post anything on the web ..which is really bad as posting it could discover the problem ....sorry...

if(c == p)..it means, i think, is that don't move the file pointer which seems to be moving...by doing this
   fseek(fp,0,SEEK_CUR); i seem to tell the file pointer dont go any where which is very strange...
Avatar of zizi21

ASKER

2)2) What is the operation you do (read or write) before the ftell?

before ftell, i did a write if there was a need as at times, you don't to do a write...
then, after ftell, i wrote the elements...and i set the position again.. using the piece of code that i posted..
Avatar of zizi21

ASKER

3) What is the operation you do (read or write) after the if..else?
After if else, i might do a write if it is needed,
Avatar of zizi21

ASKER

"if(c == p)..it means, i think, is that don't move the file pointer which seems to be moving...by doing this
   fseek(fp,0,SEEK_CUR); i seem to tell the file pointer dont go any where which is very strange..."

here seems to be the problem...as when i do this, i am getting correct output...
>> by doing this fseek(fp,0,SEEK_CUR);
>> here seems to be the problem...as when i do this, i am getting correct output...

Could you clarify what precisely the incorrect output is when you do not do this? Does it go wrong all the time (whether doing a read or write)? If doing a write, I take it that the data is being put into the wrong position.

===
One interesting thing you mentioned.
>> I face this issue on mac..but it seems to work fine (without the else on a linux server..)

I am completely unfamiliar with mac. Perhaps you can decide whether these two points are related to the different platforms:

fopen:
"You can also optionally specify the “b” flag to open a file in binary mode on Windows systems. This flag is ignored on POSIX systems (including Linux), so it's safe to always specify this flag when operating on binary files."
     http://www.cppreference.com/wiki/c/io/fopen

fseek:
"When using fseek on text files with offset values other than zero or values retrieved with ftell, bear in mind that on some platforms some format transformations occur with text files which can lead to unexpected repositioning."
     http://www.cplusplus.com/reference/clibrary/cstdio/fseek/
>> my assignment....i am not suppose to post anything on the web ..which is really bad as posting it could discover the problem

If assignment, then agreed - don't post the whole program. But if you wrote a mini-program having nothing to do with the essence and details of your assignment, but just had plain old I/O operations, then is there anything wrong with posting that? And then, if there is some behavior in this mini-program that you want to discuss, isn't that permissible?
ASKER CERTIFIED SOLUTION
Avatar of phoffric
phoffric

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of zizi21

ASKER

Could you clarify what precisely the incorrect output is when you do not do this? Does it go wrong all the time (whether doing a read or write)? If doing a write, I take it that the data is being put into the wrong position.
yes, data is being put into the wrong position
Avatar of zizi21

ASKER

Funny, am I allowed to post my code based on your words??
Thanks for posting...i wouldn't copy...i dont know where the problem is ...maybe, i am a bit tired right now...sorry..just give me a bit of time, and i would post a mini program...
>> yes, data is being put into the wrong position
Exactly how far off and in what direction?
Avatar of zizi21

ASKER

i got bad file descriptor with your code and not with mine..

fp= fopen(file,"wb"); //"wb+");
      if(fp==0)
      {
            fprintf(stderr,"\nCannot opent file.\n");

      }

is there a problem with this way ?
>> read error: Bad file descriptor
Firstly, notice that this message resulted from an error while doing a fread.

You posted code related to fopen error handling. Did you have an error with fopen? I don't have errors there. However, since you posted it, my comment is that the error test is:
     if( fp == NULL )
since it is possible for NULL to be non-zero on some systems (I've never seen it, but I have to go by what I read).

If you look at http://www.cplusplus.com/reference/clibrary/cstdio/fopen/ you see in the Return Value section is the statement:
"If the file has been succesfully opened the function will return a pointer to a FILE object that is used to identify the stream on all further operations involving it. Otherwise, a null pointer is returned."

Since a null pointer is returned as an error indicator, then you should test for a null pointer, and not 0.
Avatar of zizi21

ASKER

it works on linux systems but not on unix systems...it could be a portability issue.
What read error handling do you do? Is it similar to what I posted?

>   fseek(fp, 256, SEEK_SET );
>   n = fread( bf2, 1, 256, fp );
>   if( n != 256 ) {
Notice that is tested for n!=256 because I knew from the fseek that I should be able to read the full 256 bytes since I was not near the end of file.

Are you saying that the fread does not return an error in "wb" mode? And, if it does not return an error, are you saying that you actually are reading the data in correctly? This is surprising.
Avatar of zizi21

ASKER

it works on linux systems but not on unix systems...it could be a portability issue.

what i meant by this is that , the code works fine on linux system and not on unix system..

">> yes, data is being put into the wrong position
Exactly how far off and in what direction?"
here, instead of jumping 4 bytes after a write, it jumped 3924 bytes...
>> Since a null pointer is returned as an error indicator, then you should test for a null pointer, and not 0.

Both are the same thing. Even if the actual value of a null pointer is not an all-zero pointer, it is still safe to compare with either NULL or 0. The compiler has to do what's right to make it work.

All these are equivalent :

        if (ptr == NULL)
        if (!ptr)
        if (ptr == 0)


With regards to the question : it seems to me there is something in your code that you haven't mentioned. If you cannot post the whole code, please construct a minimal (complete and compilable) sample that exhibits the same behavior, and post that here (like phoffric suggested earlier).
Thanks for clarification about NULL... :)

Now, trying to understand one thing (at a time).

When you open using "wb", you say that you are able to read on one of the platforms.
What value do you get for n in your corresponding fread statement?
            n = fread( bf2, 1, 256, fp );

And does your buffer fill up with the correct results? Using "wb", it should not; and your return value should indicate an error.

When you open with "wb", could you add a statement like:
               char bf2[100]; // large enough to hole 4 bytes.
               n = fread( bf2, 1, 4, fp );
and verify that n == 4, where the file is well before the EOF. Then confirm that n == 4 (it shouldn't) and that bf2 is filled correctly (it should not change).

I just would like to confirm your findings that fread produces no errors when using "wb".