Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ANSI C: truncating an open file?

291 views
Skip to first unread message

Harry Potter

unread,
Nov 29, 2014, 10:29:36 AM11/29/14
to
Using ANSI C, how do I truncate a file opened with fopen() using the "r+" type after seeking to pos. 0 and rewriting the file?

Mateusz Viste

unread,
Nov 29, 2014, 12:58:41 PM11/29/14
to
On 11/29/2014 04:29 PM, Harry Potter wrote:
> Using ANSI C, how do I truncate a file opened with fopen() using the "r+" type after seeking to pos. 0 and rewriting the file?

Why don't you open it simply with "w+"? That's the most natural way to
do it...

Mateusz

Harry Potter

unread,
Nov 29, 2014, 2:02:34 PM11/29/14
to
On Saturday, November 29, 2014 12:58:41 PM UTC-5, Mateusz Viste wrote:
> Why don't you open it simply with "w+"? That's the most natural way to
> do it...
>
I was thinking of writing the file when finished only if it's changed. Also, if I do that and for some reason the program gets interrupted during the processing of the file, the whole file will be deleted. Besides that, I need to *read* the whole file first. "w+" would clear the whole file before it can even be read.

Rod Pemberton

unread,
Nov 29, 2014, 9:11:22 PM11/29/14
to
On Sat, 29 Nov 2014 14:02:33 -0500, Harry Potter <rose.j...@yahoo.com>
wrote:
> On Saturday, November 29, 2014 12:58:41 PM UTC-5, Mateusz Viste wrote:
>> On Sat, 29 Nov 2014 10:29:36 -0500, Harry Potter
>> <rose.j...@yahoo.com> wrote:

>>> Using ANSI C, how do I truncate a file opened with fopen() using the
>>> "r+" type after seeking to pos. 0 and rewriting the file?
>>>
>> Why don't you open it simply with "w+"? That's the most natural way to
>> do it...
>>
> I was thinking of writing the file when finished only if it's changed.
> Also, if I do that and for some reason the program gets interrupted
> during the processing of the file, the whole file will be deleted.
> Besides that, I need to *read* the whole file first. "w+" would clear
> the whole file before it can even be read.

What are your exact set of steps with this file?

So far you've mentioned:

1) read entire file
2) update file
3) seek pos 0 and rewrite entire file
4) conditionally truncate file

From that, I'm not quite sure what you're doing with the file or when ...

It's most likely you'll need to break this down into multiple operations,
or use multiple files.

E.g., use "r+" with fopen(), fflush() if needed, then fclose(),
then fopen() again using "w" to truncate followed by fclose(),
or remove() to delete.

E.g., it sounds like you may be overloading the use of the
file. I.e., you might better with a few temporary files
created by tmpfile(). E.g., read from one file, write
to another with any updates, delete original, rename()
new file to original.


Rod Pemberton

Harry Potter

unread,
Nov 30, 2014, 6:14:33 AM11/30/14
to
I want to read the file and keep it open, then go to the beginning of the file and re-write the file and end it there if it's smaller, then close the file. I want to keep it open to avoid corruption caused by two programs using the file at the same time. Unfortunately, now I have a more pressing problem.

Rod Pemberton

unread,
Nov 30, 2014, 3:48:25 PM11/30/14
to
On Sun, 30 Nov 2014 06:14:33 -0500, Harry Potter <rose.j...@yahoo.com>
wrote:

> I want to read the file and keep it open, then go to the beginning of
> the file and re-write the file and end it there if it's smaller, then
> close the file.

There might be a valid way to re-position the end-of-file for an updated
file in ANSI C. I'd be concerned that it wasn't safe to do or used
undefined or host-specific behavior. Also, I'm not sure how to do this ...
It seems I've never needed to know how to do this, which implies to *me*
it's most likely not something which is needed, and therefore also likely
*not* something which is available, but I don't for sure.

You could experiment to see if ftell() changes after your seek to zero
and updates. I doubt it will. My understanding is that it shouldn't.
Append and update modes allow you to add more data, but AFAIK there is
nothing to reduce the data size of the file. I.e., the old data should
still be present if it exceeds the size of the newer data. If ftell()
does change and the file size becomes smaller, then the implementation
of the file routines for your C are updating the end-of-file. Even if
it does, I would suspect this to be non-standard behavior. Obviously,
I clearly can't confirm with a high level of certainty on this.

I would probably close the file after the read. Then, write out a new
file with the changes. If the new file is to be discarded, delete it.
If the new file is to be kept, delete the old, and rename the new. I'd
do that to ensure the correct data is in the file once it's closed. This
might not be workable for your situation. See comments further below.

> I want to keep it open to avoid corruption caused by two programs
> using the file at the same time.

Why do two programs access the file at the same time? In this situation,
it's usually only safe to allow multiple access if there are no writes or
updates to the file, i.e., both apps are _only_ *reading* the file.

> [...] and re-write the file [...]
> I want to keep it open to avoid corruption caused by two programs using
> the file at the same time.

Won't re-writing the file, "corrupt" the file for the second program? ...

The second program is unlikely to be updated with the changes, unless the
first program flushes and the second program re-reads all re-written data.

Obviously, my suggestion to use multiple files isn't going to work, or
might not work portably or reliably, if you've got multiple applications
accessing the same file at the same time, _unless_ both *only* read.
The writing and updating is an issue.

Does the second application only need the original data?
Does the second application need the written updates to the file?

Personally, I see this issue as a structuring problem. I.e., you need
to change the way you're doing something in order to not do so much to
the one file by so many things, e.g., either not update the file until
some later point in time such as after the second program is done with
it, or not access the file by multiple programs, or use multiple files,
etc.


Rod Pemberton

Harry Potter

unread,
Nov 30, 2014, 4:36:54 PM11/30/14
to
On Sunday, November 30, 2014 3:48:25 PM UTC-5, Rod Pemberton wrote:
> Why do two programs access the file at the same time? In this situation,
> it's usually only safe to allow multiple access if there are no writes or
> updates to the file, i.e., both apps are _only_ *reading* the file.
>
> > [...] and re-write the file [...]
> > I want to keep it open to avoid corruption caused by two programs using
> > the file at the same time.
>
> Won't re-writing the file, "corrupt" the file for the second program? ...
>
I want the first program to *lock* the file to prevent the second program from corrupting the file while the first is trying to write to it. Fortunately, in most cases, a program may only need to *read* the file. BTW, I forgot that the program is an .ini file parser.

Rod Pemberton

unread,
Nov 30, 2014, 10:12:22 PM11/30/14
to
On Sun, 30 Nov 2014 16:36:54 -0500, Harry Potter <rose.j...@yahoo.com>
wrote:
> On Sunday, November 30, 2014 3:48:25 PM UTC-5, Rod Pemberton wrote:

>> Why do two programs access the file at the same time?
>> [...]
>> Won't re-writing the file, "corrupt" the file for the second program?
>> ...
>>
> I want the first program to *lock* the file to prevent the second
> program from corrupting the file while the first is trying to write to
> it. Fortunately, in most cases, a program may only need to *read* the
> file. BTW, I forgot that the program is an .ini file parser.

AFAIK, ANSI C doesn't provide a mechanism to lock the file.
I.e., opening a file in "w" or "a" or "+" or some combination
won't block access from other readers and writers in C. However,
the operating system (OS) might do it for you. Each OS has rules
on how a file can be accessed, single-reader, or multiple-readers,
or write-blocking, etc. Although I've programmed quite a bit for
DOS, I'm not sure what these rules are for DOS. Sorry.


If *both* programs are yours, you could program them to work
together to prevent unintentional corruption:

1) create a semaphore or mutex, if you have inter-process
communication, or some shared memory (see Wikipedia)

2) create a "lock-file" on disk

A "lock-file" is used to control access via it's presence or absence.
I.e., app #1 creates an empty file to be used as the lock when it
wants to prevent app #2 from using the .ini file. When app #1 is
finished, it deletes the empty file. App #2 checks to see if the
empty file is present before doing anything with the .ini. If the
empty file is present, then app #2 can't write or modify the .ini
file. It waits, looping until the empty file is deleted. If the
empty file isn't present, then app #2 has access to the .ini file.
If app #2 takes a long time to do it's thing and app #1 creates
and deletes many empty lock-files, you many need another empty file
to block app #1 from accessing the .ini while app #2 is using the
.ini ... This is a way of synchronizing access to the shared .ini
file.


Rod Pemberton

R.Wieser

unread,
Dec 1, 2014, 5:22:10 AM12/1/14
to
Harry,

> Using ANSI C, how do I truncate a file opened with fopen()
> using the "r+" type after seeking to pos. 0 and rewriting the file?

As far as I remember the "r+" mode sets the "cooked" mode, meaning the file
is handled as a textfile. In that case you should be able to write a
CTRL-Z (0x1A) into the file.

The file won't get any smaller, but the C functions will, in cooked mode,
regard that character as the EOF (End Of File) and ignore (won't read) any
data beyond it.


For actal file resizing google returned a site named "stackoverflow" (result
#2) in which someone suggested "_chsize( fileno(f), size);". No idea if it
works though (Keywords used: "C++ file truncate" <-- thats a hint. Finding
the above answer did cost me less than 5 minutes).

The same google result page also mentioned (result #8) the what to use in
case Win32 functions are used: SetEndOfFile

Regards,
Rudy Wieser


-- Origional message:
Harry Potter <rose.j...@yahoo.com> schreef in berichtnieuws
85050168-df85-4d9c...@googlegroups.com...

Harry Potter

unread,
Dec 1, 2014, 7:58:55 AM12/1/14
to
On Sunday, November 30, 2014 10:12:22 PM UTC-5, Rod Pemberton wrote:
> AFAIK, ANSI C doesn't provide a mechanism to lock the file.
>
Oh. :(

> If *both* programs are yours, you could program them to work
> together to prevent unintentional corruption:
>
The program on which I'm working is an .ini file parser written in ANSI C and to be used by multiple programs. My concern is if two programs open the same .ini file for writing.

> 1) create a semaphore or mutex, if you have inter-process
> communication, or some shared memory (see Wikipedia)
>
I don't understand that. :(

> 2) create a "lock-file" on disk
>
> A "lock-file" is used to control access via it's presence or absence.
> I.e., app #1 creates an empty file to be used as the lock when it
> wants to prevent app #2 from using the .ini file. When app #1 is
> finished, it deletes the empty file. App #2 checks to see if the
> empty file is present before doing anything with the .ini. If the
> empty file is present, then app #2 can't write or modify the .ini
> file. It waits, looping until the empty file is deleted. If the
> empty file isn't present, then app #2 has access to the .ini file.
> If app #2 takes a long time to do it's thing and app #1 creates
> and deletes many empty lock-files, you many need another empty file
> to block app #1 from accessing the .ini while app #2 is using the
> .ini ... This is a way of synchronizing access to the shared .ini
> file.
>
That's a good idea. Perhaps I'll recommend it in the program's source code.
0 new messages