Size of file

M

MisterE

I hear that this isn't always valid:

FILE *in;
long size;
in = fopen("foo.bar","rb");
fseek(in,0,SEEK_END);
size = ftell(in);
fseek(in,0,SEEK_SET);

then fread size many bytes into memory.

Apparently fseek is not guaranteed to work because of 0xFF EOF or other
characters, is this true only in text mode or also in binary mode? Is there
anyway to get a filesize without having to read bytes on at a time. Is it
best to just fread until it fails?
 
B

Bartc

MisterE said:
I hear that this isn't always valid:

FILE *in;
long size;
in = fopen("foo.bar","rb");
fseek(in,0,SEEK_END);
size = ftell(in);
fseek(in,0,SEEK_SET);

then fread size many bytes into memory.

Apparently fseek is not guaranteed to work because of 0xFF EOF or other
characters, is this true only in text mode or also in binary mode? Is
there anyway to get a filesize without having to read bytes on at a time.
Is it best to just fread until it fails?

Works for me, using binary mode files. But there are various pitfalls:

In text mode, the size you get might be wrong because it might include '\n'
'\r' sequences instead of just '\n'.

Some types of files may not have a beginning or end (like stdin, or some
serial device), so don't have a size.

Some OSs may not store the exact bytesize of a file (for example may only
store a block size), so the value might be approximate. (And there might be
other OS things to bear in mind such as use of compression.)

And whatever file size you get might change if the file is modified (by any
other process) by the time you use the file size information.

For more details, see threads on this subject in c.l.c.

But within those constraints, I've been using code like yours successfully
for a decade or two.
 
B

Barry Schwarz

I hear that this isn't always valid:

You heard right.
FILE *in;
long size;
in = fopen("foo.bar","rb");

You open the file in binary.
fseek(in,0,SEEK_END);

The standard specifically states "A binary stream need not
meaningfully support fseek calls with a whence value of SEEK_END."
size = ftell(in);
fseek(in,0,SEEK_SET);

then fread size many bytes into memory.

Apparently fseek is not guaranteed to work because of 0xFF EOF or other

I don't where you came up with this. 0xFF is not a special character
in a binary file. It could even be a normal printable character since
the standard does not mandate ASCII or EBCDIC. EOF is not a
character. It is a macro. It is entirely possible that the value
used in that macro is not representable as a char.
characters, is this true only in text mode or also in binary mode? Is there
anyway to get a filesize without having to read bytes on at a time. Is it
best to just fread until it fails?

Depends on how important portability is to you.
 
A

arnuld

I hear that this isn't always valid:

FILE *in;
long size;
in = fopen("foo.bar","rb");
fseek(in,0,SEEK_END);
size = ftell(in);
fseek(in,0,SEEK_SET);

then fread size many bytes into memory.

Most people use fopen and fseek. In my programs I used stat. One thing
that always made me wonder is that stat reports filesize == 0 if the file
is opened . Only on closed file it reports the correct size.
 
N

Nate Eldredge

arnuld said:
Most people use fopen and fseek. In my programs I used stat. One thing
that always made me wonder is that stat reports filesize == 0 if the file
is opened . Only on closed file it reports the correct size.

Sorry this is becoming off-topic, but where did you find this
behavior? Under Unix this would be very strange.

The only thing I can think of is that you opened the file for writing,
which ordinarily would truncate it, so that its size would indeed be
0. But opening for reading should not do this.
 
A

arnuld

Sorry this is becoming off-topic, but where did you find this
behavior? Under Unix this would be very strange.

well, it happens on my machine all the time.

The only thing I can think of is that you opened the file for writing,
which ordinarily would truncate it, so that its size would indeed be
0. But opening for reading should not do this.

fopen(file, "a")
 
C

CBFalconer

arnuld said:
Most people use fopen and fseek. In my programs I used stat. One
thing that always made me wonder is that stat reports filesize
== 0 if the file is opened . Only on closed file it reports the
correct size.

stat is not present in standard C. Thus it can do anything, and is
off topic here unless you present its actual coding (in standard
C).
 
A

Antoninus Twink

I don't know exactly what you mean. Perhaps you're talking about writes
that might have been buffered and not yet actually made, which stat()
won't detect? For example:


#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(void)
{
FILE *out;
struct stat buf;
out=fopen("foo", "w");
if(out) {
fputs("12345", out);
if(stat("foo", &buf)==0)
printf("size: %lu\n", (unsigned long) buf.st_size);
fflush(out);
if(stat("foo", &buf)==0)
printf("flushed size: %lu\n", (unsigned long) buf.st_size);
fclose(out);
}
return 0;
}

$ ./a
size: 0
flushed size: 5
stat is not present in standard C. Thus it can do anything, and is
off topic here unless you present its actual coding (in standard
C).

Why don't you just crawl back in your hole and die if you don't have
anything useful to contribute?
 
C

Chris Ahlstrom

After takin' a swig o' grog, CBFalconer belched out
this bit o' wisdom:
stat is not present in standard C. Thus it can do anything, and is
off topic here unless you present its actual coding (in standard
C).

It's called _stat() by Microsoft.
 
K

Kenny McCormack

Antoninus Twink <[email protected]> plaintively asked of our good
friend CBF:
....
Why don't you just crawl back in your hole and die if you don't have
anything useful to contribute?

Actually, I think that CBF performs a useful function here, which is
demonstrating, to the next rung (*), just how absurd this "off topic,
blah, blah, blah" routine is. I.e., I think even the hardcore regs
(meaning: KT and RH, and their respective coteries) are beginning to see
how ridiculous it is to mouth this inanity at every opportunity.

(*) Clarification: What I mean here is that anyone with any common sense
(which, in this newsgroup, means those referred to as "trolls") could
see the inanity already, once I started doing my by now famous:

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.

routine, but what we needed was something to get through to those who
are on the next step below on the intelligence ladder. I think CBF is
performing that function admirably.
 
K

Keith Thompson

CBFalconer said:
arnuld wrote: [...]
Most people use fopen and fseek. In my programs I used stat. One
thing that always made me wonder is that stat reports filesize
== 0 if the file is opened . Only on closed file it reports the
correct size.

stat is not present in standard C. Thus it can do anything, and is
off topic here unless you present its actual coding (in standard
C).

Let's assume that arnuld is referring to the "stat" function specified
by POSIX; it's theoretically possible that he's talking about
something else, but common sense points to that one particular
function. Presenting an actual implementation of the POSIX stat() in
standard C is not possible; it depends on characteristics of the file
system that C does not define. Even if it were possible, posting a
complete implementation would be a waste of bandwidth; you don't need
to post a fucntion's implementation to discuss what it does.

If you want to say it's off-topic, just say it's off-topic (and I
agree, it is off-topic, though I don't object to a brief mention).
Dragging in absurd, and presumably unserious, suggestions about how it
*could* be topical is not at all helpful.
 
C

CBFalconer

Chris said:
CBFalconer belched out this bit o' wisdom:

It's called _stat() by Microsoft.

So what? It is not present in standard C, the subject of this
newsgroup. If you want to bring it up on a newsgroup that deals
with Microsoft or Posix, that is another matter. Then there is a
definition available for it. It still isn't portable.
 
C

CBFalconer

Keith said:
.... snip ...

.... snip ...

If you want to say it's off-topic, just say it's off-topic (and
I agree, it is off-topic, though I don't object to a brief
mention). Dragging in absurd, and presumably unserious,
suggestions about how it *could* be topical is not at all helpful.

I disagree. There is no reason a user can't write his own stat()
function, say as:

int stat(char *s) {
return !!*s;
}

I think my response (above) covered the possibilities.
 
K

Keith Thompson

CBFalconer said:
I disagree. There is no reason a user can't write his own stat()
function, say as:

int stat(char *s) {
return !!*s;
}

I think my response (above) covered the possibilities.

The previous poster talked about using stat to determine the size of a
file.

Topicality doesn't preclude using a little common sense. When you
talk about Pascal, I generally assume you mean the language, not the
philosopher.
 
A

arnuld

What operating system / compiler / standard library?

[arnuld@dune ~]$ uname -a
Linux dune 2.6.9-67.EL #1 Fri Nov 16 12:34:13 EST 2007 i686 athlon i386 GNU/Linux

[arnuld@dune ~]$ cat /etc/issue
CentOS release 4.6 (Final)
Kernel \r on an \m

[arnuld@dune ~]$ gcc --version
gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-9)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Peculiar. Can you post a complete example of a program that shows
this behavior?

yeah, quite peculiar because its working fine now:


#include <stdio.h>
#include <sys/stat.h>



int main(void)
{
FILE* fp = NULL;
char file_name[] = "test.c";
char* pf = file_name;
struct stat statbuf;
unsigned long file_size = 0;


if( (fp = fopen(pf, "a")) )
{
if( ! stat(pf, &statbuf) )
{
file_size = statbuf.st_size;
}
}


if( fclose(fp) )
{
printf("error closing file\n");
}

printf("size of %s = %ld bytes\n", file_name, file_size);


return 0;
}
====================== OUTPUT ===========================
[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra new.c
[arnuld@dune ztest]$ ./a.out
size of test.c = 256 bytes
[arnuld@dune ztest]$



I don't know why it was behaving like that last time. May be you are write
because sometimes the program was to create new file while sometimes that
was supposed to append.
 
R

Richard Bos

Chris Ahlstrom said:
After takin' a swig o' grog, CBFalconer belched out


It's called _stat() by Microsoft.

Does it work _exactly_ the same as stat() under POSIX? _All_ POSIXes?
No? Well, it's not very dependable, then, is it?

Richard
 

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,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top