Is it recommended to use the method of calculating the file size using fseek ()?

In C, we can find the file size using the fseek() function. How,

 if (fseek(fp, 0L, SEEK_END) != 0) { // Handle repositioning error } 

So, I have a question: is it recommended to use the method of calculating the file size using fseek() and ftell() ?

+3
c file
source share
4 answers

If you are running Linux or some other UNIX system, then you need the stat function:

 struct stat statbuf; int rval; rval = stat(path_to_file, &statbuf); if (rval == -1) { perror("stat failed"); } else { printf("file size = %lld\n", (long long)statbuf.st_size; } 

On Windows under MSVC, you can use _stati64 :

 struct _stati64 statbuf; int rval; rval = _stati64(path_to_file, &statbuf); if (rval == -1) { perror("_stati64 failed"); } else { printf("file size = %lld\n", (long long)statbuf.st_size; } 

Unlike using fseek , this method does not involve opening a file or searching through it. It just reads the file metadata.

+7
source share

fseek()/ftell() works sometimes.

 if (fseek(fp, 0L, SEEK_END) != 0) printf("Size: %ld\n", ftell(fp)); } 

Problems.

  • If the file size exceeds approximately LONG_MAX , the answer long int ftell(FILE *stream) problematic.

  • If the file is opened in text mode, the return value from ftell() may not match the length of the file. "For a text stream, the file position indicator contains undefined information," C11dr ยง7.21.9.4 2

  • If the file is opened in binary mode, fseek(fp, 0L, SEEK_END) is undefined. "Setting the file position indicator to the end of the file, like fseek(file, 0, SEEK_END) , has undefined behavior for the binary stream (due to possible terminating null characters) or for any stream with a state-dependent encoding that does not necessarily end in the initial state of shear. " C11dr footnote 268. @Evert This most often refers to earlier platforms than today, but is still part of the specification.

  • If the file is a stream as serial input or stdin , fseek(file, 0, SEEK_END) makes little sense.

The usual solution for finding file size is a non-portable platform. An example of a good @ dbush answer.

Note. If the code tries to allocate memory based on file size, the available memory can easily be exceeded by file size.

Due to these issues, I do not recommend this approach.

As a rule, the problem should be reworked so that you do not need to find the file size, but in order to increase the data as more input data is processed.


LL disclaimer: note that C spec footnotes are informative and therefore not necessarily normative.

+4
source share

The best method, in my opinion, is fstat() : https://linux.die.net/man/2/fstat

0
source share

Well, you can estimate file size in several ways:

  • You can read(2) save the file from beginning to end, and the number or number of characters is the file size. This is a tedious way to get the file size, since you need to read the entire file to get the size. But if the operating system does not allow you to randomly position the file pointer, this is the only way to get the file size.
  • Or you can move the pointer at the end of the file position. This is the lseek(2) you pointed out in the question, but be careful to make the system call twice , since the return value is the actual position before , moving the pointer to the right place.
  • Or you can use the stat(2) system call, which will tell you all the administrative information of the file, such as the owner, group, permissions, size, the number of blocks the file occupies on the disk, the disk belongs to this to file, the number of entries in directory pointing to it, etc. This allows you to get all this information with just one system call.

Other methods that you specify (for example, using the ftell(3) stdio library call) will also work (with the same problem as the two system calls to set and retrieve / restore the file pointer), but the problem including libraries, which you probablyโ€™re not using for anything else. It would be difficult to get the FILE * pointer (for example, fdopen(3) ) in the int file descriptor to be able to use the ftell(3) function on it (twice) and then fclose(3) again.

0
source share

All Articles