www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/09/30/08:05:09

Date: Tue, 30 Sep 1997 14:03:26 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Ingo Ruhnke <ruhnke AT owl-online DOT de>
cc: djgpp AT delorie DOT com
Subject: Re: How to get file size?
In-Reply-To: <01bccc5b$8138ba00$0200a8c0@ingo>
Message-ID: <Pine.SUN.3.91.970930140242.6040Q-100000@is>
MIME-Version: 1.0

On 29 Sep 1997, Ingo Ruhnke wrote:

> I want to read a ASCII Text file, therefore I do allocate some memory with
> malloc() and therefore I need the filesize, more exactly the number of
> characters. At the moment I use this to get the file size:
> 
> filelength(fileno(FILE *))
> 
> This returns me the number of bytes of the file, but the number of chars is
> a little bit smaller, because of the <LF><CR>.
> So is there a standart way to get the number of chars in a file?

AFAIK, there's no way of knowing up front how many characters will be
stripped when the library functions read a file in text mode.  The
amount could be anywhere between zero (if this is a Unix-style text
file) to as much as half the size of the original file (for a file
that only has empty lines with a CR-LF pair at the end).  DOS doesn't
store any information that would allow to compute the amount of
stripped characters.  The only way to know is to read the file and
examine the value returned by `read' or `fread' library functions.

However, in most cases, the amount of stripped characters is small
(typically, about 2% for a text file, 5% for a C source).  So you
don't waste much memory by allocating a buffer the size of the
original file.

If these small percents do make a difference, you can always
reallocate the buffer once you have read the file.  For example,
consider the next (untested) code fragment:

	 #include <stdio.h>
	 #include <stdlib.h>
	 #include <io.h>
	 ...
	 FILE *fp = fopen ("foo.txt", "rt");
	 size_t file_size_on_disk = (fp ? filelength (fileno (fp)) : 0);
	 char *buf = (char *)malloc (file_size_on_disk);
	 size_t file_size_in_memory 
              = (fp && buf ? fread (buf, 1, file_size_in_memory, fp)
			   : 0);

	 if (file_size_in_memory < file_size_on_disk)
	   buf = (char *)realloc (buf, file_size_in_memory);

As an aside, please note that `filelength' is non-POSIX and therefore
not-so-portable.  A more portable way to get the size of a file is to
use `stat' or `fstat' library functions; another portable way is to
use `lseek' or `fseek'.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019