How to get file size?

S

Sam

Hi all,
Is there a function in the standard library that can get the size of a file?
Thank you very much.
Sam.
 
C

copx

Sam said:
Hi all,
Is there a function in the standard library that can get the size of a
file?

Not really but you can easily make one using ftell/fseek.
This should work:

/*
* returns the length of a file (in bytes)
*/
int file_length(FILE *f)
{
int pos;
int end;

pos = ftell (f);
fseek (f, 0, SEEK_END);
end = ftell (f);
fseek (f, pos, SEEK_SET);

return end;
}


HTH,
copx
 
R

Richard Bos

copx said:
Not really but you can easily make one using ftell/fseek.

No, you cannot. _Read_ the newsgroup: this has already come up earlier
today said:
This should work:

No, it shouldn't. ftell() is meaningful only for binary streams, fseek()
to SEEK_END only for text streams.

Richard
 
C

copx

Richard Bos said:
No, you cannot. _Read_ the newsgroup: this has already come up earlier


No, it shouldn't. ftell() is meaningful only for binary streams, fseek()
to SEEK_END only for text streams.

But it does. The code is actually an almost straight copy form the Quake 2
source. It does work, on Linux and Windows. Using GCC or multiple Windows
compilers. I mean if it's good enough for ID software it's probably good
enough for everybody.
IMO you're way too academic (i.e. out of touch with programming reality)
here. Where does this NOT work? On the Deathstation 9000?

copx
 
R

Richard Bos

copx said:
But it does.

Chapter and verse, please.
The code is actually an almost straight copy form the Quake 2
source.

So bloody what? I could copy code from my programs that involves
WinMain(), initgraph() and setmode(), but that doesn't mean that any of
those are correct ISO C, or on topic in this newsgroup.
I mean if it's good enough for ID software it's probably good
enough for everybody.

I hope never to encounter a program written by you. They don't work,
they "work" "good enough". As a sysadmin, I want programs that I _know_
work, not that someone has guessed probably would work everywhere he
could think of.

Richard
 
E

Eric Sosman

copx said:
But it does. The code is actually an almost straight copy form the Quake 2
source. It does work, on Linux and Windows.

Would you care to place a small wager? Despite your
assertion, it does not "work" on Windows. Try it on any
non-empty Windows text file of your choosing, and compare
the result to what you get by reading and counting the
characters one by one.
Using GCC or multiple Windows
compilers. I mean if it's good enough for ID software it's probably good
enough for everybody.

Yurrgh ...
IMO you're way too academic (i.e. out of touch with programming reality)
here. Where does this NOT work? On the Deathstation 9000?

Doesn't work on Windows, as mentioned above. Doesn't
work on "native" text files on OpenVMS. Doesn't work on
any text file that represents end-of-line by anything other
than precisely one byte.[*]

[*] Assuming an fseek() implementation that uses "random
access." It would be possible to implement fseek() in terms
of rewind() and a character-counting loop, with assistance
from the implementations of some other <stdio.h> functions,
but an fseek() that can "jump to the end" will be unable to
count the number of line terminators in the skipped portion.

IMO you're way too eager to generalize limited experience
into Universal Truth -- especially since your own experience,
had you bothered to examine it, would have contradicted your
generalization. You're not out of touch with programming
reality, you're *in* touch with programming fiction.
 
C

copx

Richard Bos said:
Chapter and verse, please.

This reminds of a theological discussion...
So bloody what? I could copy code from my programs that involves
WinMain(), initgraph() and setmode(), but that doesn't mean that any of
those are correct ISO C, or on topic in this newsgroup.

I didn't claim that the standard guarantees that it works. However the OP
may doesn't care because he wants to solve a practical programming problem
not worship sacred texts.
I hope never to encounter a program written by you. They don't work,
they "work" "good enough". As a sysadmin, I want programs that I _know_
work, not that someone has guessed probably would work everywhere he
could think of.

Just because the ISO C standard says something should work in a specific way
doesn't mean that it actually works this way in REALITY.
And as a sysadim you rely on a lot of non-standardized functionality that
just works because it works and not because some ancient scripture demands
that it works.

BTW in general I try to stick to ISO C and write portable code but at a
certain point portability concerns become ridiculous...

copx
 
R

Richard Bos

copx said:
Just because the ISO C standard says something should work in a specific way
doesn't mean that it actually works this way in REALITY.
And as a sysadim you rely on a lot of non-standardized functionality that
just works because it works and not because some ancient scripture demands
that it works.

BTW in general I try to stick to ISO C and write portable code but at a
certain point portability concerns become ridiculous...

I stand by my comments. If you need system-specific functionality, write
_correct_ system-specific code (and post it elsewhere). If you want to
resort to unreliable hacks, get the **** off my system. There is a
correct, but system-specific, solution to the file size problem, for the
systems you claim (probably erroneously) your hack works on. Being
system-specific, it is off-topic in comp.lang.c.

Richard
 
C

copx

[snip]
Would you care to place a small wager? Despite your
assertion, it does not "work" on Windows. Try it on any
non-empty Windows text file of your choosing, and compare
the result to what you get by reading and counting the
characters one by one.
[snip]

If you say it it's probably true I didn't thought of "text files" they are a
platform-specific thing anyway ;)
It works in binary mode on all relevant desktop platforms and that might be
more than enough for the OP.

copx
 
W

Walter Roberson

I hope never to encounter a program written by you. They don't work,
they "work" "good enough". As a sysadmin, I want programs that I _know_
work, not that someone has guessed probably would work everywhere he
could think of.

As a fellow sysadmin who also does software development
(some scientific, some tools for administration purposes), I would
ask where you find the *time* to make meaningful programs that are
completely portable and bug free?

Suppose, for example, that you are in the middle of 50,000 lines
of code, and you've done all the error bounds analysis and
you've sorted your values before totalling them and so on, and
you've put in cases for near singularities... and then you realize
that there is -no- known answer for how to handle some of the
extrema. What then? Do you take the next 2 or 3 decades to
invent a new form of logical or mathematical analysis to solve
the "corner case" just so you "_know_" the program will work? Or
do you document the condition, put in a smooth failure mode for it,
and let it go?


What do you do when you need an SNMP probe, or need a modem or
'expect' chat script, or need your program to send an email alert?
SNMP and SMTP and sockets and pty and device control are all beyond
the scope of Standard C. Do you refuse to write the tool, on the
grounds that someone might want to -try- to run it on (say) a
cell phone with no Internet link?


I don't know what things are like where you are, but hereabouts,
sysadmin work is full of compromises. The goal around here isn't
to be perfect, but rather to do the best balancing of priorities and
budgets and available time that one can do. The boss doesn't want
the numbers 3 months from now, the boss wants the numbers this afternoon,
because the grant proposal has to be in by 9:00 AM the next morning.
The network management tool doesn't have to support every known model
of network device: the network is ill -now-. The network is under
attack -now-, so don't worry that in theory a firewall interface
name might include an internal colon as well as the usual terminal
colon: do what you need to do NOW. You can clean up later if you ever
manage to "get all the fires put out."
 
C

Christopher Benson-Manica

copx said:
I didn't claim that the standard guarantees that it works. However the OP
may doesn't care because he wants to solve a practical programming problem
not worship sacred texts.

The OP may also appreciate knowing that your proposed solution is dubious
at best.
Just because the ISO C standard says something should work in a specific way
doesn't mean that it actually works this way in REALITY.

If something doesn't work the way the ANSI standard says it should,
the implementation in question is not a C implementation. End of story.
And as a sysadim you rely on a lot of non-standardized functionality that
just works because it works and not because some ancient scripture demands
that it works.

I hardly think the ANSI standard qualifies as "ancient scripture".
 
R

Richard Bos

As a fellow sysadmin who also does software development
(some scientific, some tools for administration purposes), I would
ask where you find the *time* to make meaningful programs that are
completely portable and bug free?

I wrote that I want such programs, not that I always get what I want
:-/. AAMOF, since most of our desktop machines are MS-Windows (for
reasons of *hack* *spit* market compatibility), I know that I never do
completely get what I want. Nevertheless, when I encounter a program
that I _know_ contains such ill-advised code as that under discussion, I
will endeavour not to employ it (and probably get overruled by my B's
PHB's and their *expectorate* market forces, but at least I'll have done
my duty).
What do you do when you need an SNMP probe, or need a modem or
'expect' chat script, or need your program to send an email alert?
SNMP and SMTP and sockets and pty and device control are all beyond
the scope of Standard C.

Don't be daft. As I already wrote upthread, there are right ways and
wrong ways to write programs which are inherently system-dependent. And
this was a wrong way.

Richard
 
J

jacob navia

Dear copx
I proposed several months ago the same solution as you and
received the same pompous answers as you have received.

I have never seen any system where that would fail, sorry.
And the guys throwing nonsense didn't ever show me an example
where this would fail:

1:
Open file under binary mode
2:
Go to end

3:
measure position

4:
close

5:
return position as file length.

I have never seen a system where setting the file pointer at
the end would fail.

But maybe, as you proposed, in DeathSystem 9000 it doesn't work...

I think the best thing to do is to ignore this guys.
 
E

Eric Sosman

Christopher said:
Ignoring Mr. Sosman and Mr. Bos would be colossally stupid.

Ignoring Mr. Sosman is sometimes a good idea, but not in
this case. (Or so it seems to me ...)

In the case at hand, my experience is at variance with
that reported by Mr. Navia, who argues that opening a
binary stream, seeking to the end, and reporting the ftell()
value as the file size is reliable. "I have never seen a
system where setting the file pointer at the end would fail,"
he writes. Well, neither have I ...

... but I *have* seen systems where the result of this
query is (or can be) useless. It tells you how many bytes
you could read from the file with a binary stream, but that
number is only one of several notions of "file size," and
possibly not the notion that the programmer cares about.

The usual reason for wanting to know "the" size of a file
in a C program is to decide how much memory to allocate to
hold the file's content. If the file is in fact a big bag of
binary bytes, Navia's computation will work on every system
I've seen (even though the Standard specifically disavows it,
which suggests that I haven't seen all systems). If the file
is textual, though, and will eventually be read with a text
stream, Navia's result may be well off the mark. Two cases
from real life:

- Navia can overestimate the character count by failing
to account for the translation of multi-byte line-
delimiting sequences to single newline characters.
The commonest example may be Windows' conversion
between \r\n and \n, but others exist -- I've used
one system where the line delimiter can be as long
as *five* bytes.

- Navia can *under*estimate the character count by
being blind to special formatting codes in the file.
This can happen on OpenVMS, where one of the file
formats puts a control prefix on each line indicating
the desired vertical spacing: leave so-and-so many
blank lines before/after this one. When translated
by a text stream, such a prefix can synthesize a
potentially large number of \n characters not actually
present on the disk.

Mr. Navia is a knowledgeable user of C, but in this matter
(as in others) he demonstrates that portability is not among
his principal concerns.

(Pompous enough for ya, Jacob?)
 
J

jacob navia

Eric said:
Ignoring Mr. Sosman is sometimes a good idea, but not in
this case. (Or so it seems to me ...)

In the case at hand, my experience is at variance with
that reported by Mr. Navia, who argues that opening a
binary stream, seeking to the end, and reporting the ftell()
value as the file size is reliable. "I have never seen a
system where setting the file pointer at the end would fail,"
he writes. Well, neither have I ...

OK Eric at least we agree with that.
... but I *have* seen systems where the result of this
query is (or can be) useless. It tells you how many bytes
you could read from the file with a binary stream, but that
number is only one of several notions of "file size," and
possibly not the notion that the programmer cares about.

File size is the number of bytes you get when reading the stuff
in binary mode. As far as I understand this complicated subject,
when you make "DIR" or "ls -l" or whatever your system command
is, the size reported is the actual number of bytes in the "file"
entity. This is (or should be) the same as reported by the above
method.
The usual reason for wanting to know "the" size of a file
in a C program is to decide how much memory to allocate to
hold the file's content. If the file is in fact a big bag of
binary bytes, Navia's computation will work on every system
I've seen (even though the Standard specifically disavows it,
which suggests that I haven't seen all systems). If the file
is textual, though, and will eventually be read with a text
stream, Navia's result may be well off the mark. Two cases
from real life:

- Navia can overestimate the character count by failing
to account for the translation of multi-byte line-
delimiting sequences to single newline characters.
The commonest example may be Windows' conversion
between \r\n and \n, but others exist -- I've used
one system where the line delimiter can be as long
as *five* bytes.

This is outside the specs. If you read it in text mode this
can be off the mark. A little bit oversize is a very mild bug though.
- Navia can *under*estimate the character count by
being blind to special formatting codes in the file.
This can happen on OpenVMS, where one of the file
formats puts a control prefix on each line indicating
the desired vertical spacing: leave so-and-so many
blank lines before/after this one. When translated
by a text stream, such a prefix can synthesize a
potentially large number of \n characters not actually
present on the disk.

Ahhh no wonder Digital went under... what a system!

If your "text" mode includes translating tabs into blanks for instance,
that WILL go wrong. But again, we are speaking about BINARY mode
Eric. JUST BINARY MODE ok?

Mr. Navia is a knowledgeable user of C, but in this matter
(as in others) he demonstrates that portability is not among
his principal concerns.

(Pompous enough for ya, Jacob?)

Well, yeah can go :)
 
J

Jean-Sebastien Samson

1: Open file under binary mode
2: Go to end
3: measure position
4: close
5: return position as file length.

I am not too much concerned about portability here but beware of race
conditions (especially with other processes). If you open a file and close
it, you never know what you will get when you reopen it. You may face a
security problem.
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top