Overwriting a portion of a binary file

M

mohammad.nabil.h

I've been working on a database management system, and i have met a
problem when i update a row, i found that fwrite() and _write, writes
to the end of the file, even if i hade rewind() the file before it. As
far as i can guess, they `append', i am looking for something that
overwrites. of course i can't load the 'whole' file in memory, change
it, then resave it again. the whole memory might not be enough.

my code always insists on storing 'bar' after 'foo'. i want to save
'bar' instead of 'foo'

here is a peek of my code :
main.cpp
//...
record records1[] = { {0,"foo",10} , {1,"bob",4} };

add_record(records1);
add_record(records1+1);

reset_to_file_start();

record records2[] = { {0,"bar",10} , {1,"bob",4} }; // 'bar' shud
instead of 'foo'

add_record(records2);
add_record(records2+1);
//..
void add_record(record* rec)
{
// m_db is a FILE*
//fseek(m_db,0,SEEK_END);
//fwrite(rec,record_size(),1,m_db);
_write(fileno(m_db),rec,record_size()); // both function result in the
same output
}
void reset_to_file_start()
{
rewind(m_db);
}

any help greatly appreciated
 
D

Default User

I've been working on a database management system, and i have met a
problem when i update a row, i found that fwrite() and _write, writes
to the end of the file, even if i hade rewind() the file before it. As
far as i can guess, they `append', i am looking for something that
overwrites. of course i can't load the 'whole' file in memory, change
it, then resave it again. the whole memory might not be enough.

my code always insists on storing 'bar' after 'foo'. i want to save
'bar' instead of 'foo'

here is a peek of my code :

We don't want a peek, we want a long, lingering look at the whole thing.

void add_record(record* rec)
{
// m_db is a FILE*

Where is the code that created this FILE*?
//fseek(m_db,0,SEEK_END);
//fwrite(rec,record_size(),1,m_db);
_write(fileno(m_db),rec,record_size()); // both function result in
the same output

There is no _write() function in the C language.
any help greatly appreciated

Post a complete, minimal, compilable program that demonstrates the
problem.



Brian
 
M

Mark McIntyre

On 26 Jan 2006 15:17:13 -0800, in comp.lang.c ,
I've been working on a database management system, and i have met a
problem when i update a row, i found that fwrite() and _write, writes
to the end of the file, even if i hade rewind() the file before it. As
far as i can guess, they `append',

by default, fopen() opens a file for writing at the end. You'd need to
move elsewhere in the file if you want to overwrite.

i am looking for something that
overwrites. of course i can't load the 'whole' file in memory, change
it, then resave it again. the whole memory might not be enough.

This is a FAQ - 19.14. The answer is that generally you can't do this
efficiently.

Assuming you only want to overwrite a record however, you MAY be able
to open the file for update, move to the start of the record you want
to change, then write some data. How you'd find that, is an exercise
for the reader, given that fseek() isn't guaranteed to work.

By the way, your code (reworked into C) works for me. I suspect one of
the parts you didn't post is causing a problem.

#include <stdio.h>

typedef struct record
{ int a; char b[4]; int d;
}record;

FILE* m_db;

int record_size = sizeof(struct record);

void add_record(record* rec)
{
// m_db is a FILE*
//fseek(m_db,0,SEEK_END);
fwrite(rec,record_size,1,m_db);
}
void reset_to_file_start()
{
rewind(m_db);
}


int main ()
{
record records1[] = { {0,"foo",10} , {1,"bob",4} };
record records2[] = { {0,"bar",7} , {1,"bob",3} };

m_db = fopen("d:/temp/test.txt","wb");
add_record(records1);
add_record(records1+1);

reset_to_file_start();

add_record(records2);
add_record(records2+1);
fclose(m_db);
}

bar
bob

Mark McIntyre
 
M

mohammad.nabil.h

thanks very very much for ur help,
actually my program was opening the file as "ab+" not as "wb", looke
like ab+ just "appends" and doesn't allow modifications. the replace
worked fine after opening it as "wb+", but wb+ erases the file every
time. so opening it as rb+ solved the problem except that it does not
create a new file if it doesn't exist... so i guess the `hybrid'
solution is to use rb+ and if the file doesn't exits use wb+.

here the minimal code after a lot of reductions to demonstrate the
problem as `default user' requested:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>

FILE* m_db;

typedef struct record
{
int pk;
char CustomerName[10];
int Age;
}record;

void assign_file(char* dbname);
void add_record(record* rec);

void main(void)
{
int i;
int record_count;

record records1[] = { {0,"foo",10} , {1,"bob",4} };
record records2[] = { {0,"bar",10} , {1,"bob",4} }; // bar shud
replace foo

assign_file("db1");

add_record(records1);
add_record(records1+1);

//rewind(m_db); // uncomment to test replacemnt

add_record(records2);
add_record(records2+1);

fflush(m_db);
fclose(m_db);
}

void assign_file(char* dbname)
{
char dbfilename[40] = { 0 };
strcat(dbfilename,dbname);
strcat(dbfilename,".txt");
m_db = fopen(dbfilename,"rb+");
fseek(m_db,0,SEEK_END);
rewind(m_db); // comment to test appending
}

void add_record(record* rec)
{
//fwrite(rec,sizeof(record),1,m_db);
_write(fileno(m_db),rec,sizeof(record));
}
 

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

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,816
Latest member
nipsseyhussle

Latest Threads

Top