Check the File-Size Without Opening File in C++

How can I get a file's size in C?

You need to seek to the end of the file and then ask for the position:

fseek(fp, 0L, SEEK_END);
sz = ftell(fp);

You can then seek back, e.g.:

fseek(fp, 0L, SEEK_SET);

or (if seeking to go to the beginning)

rewind(fp);

How can I get a file's size in C++?

#include <fstream>

std::ifstream::pos_type filesize(const char* filename)
{
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
return in.tellg();
}

See http://www.cplusplus.com/doc/tutorial/files/ for more information on files in C++.

edit: this answer is not correct since tellg() does not necessarily return the right value. See http://stackoverflow.com/a/22986486/1835769

Proper way to get file size in C

Regular file means that it is nothing special like device, socket, pipe etc. but "normal" file.
It seems that by your task description before sending you must retrieve size of normal file.
So your way is right:

FILE* fp = fopen(...);
if(fp) {
fseek(fp, 0 , SEEK_END);
long fileSize = ftell(fp);
fseek(fp, 0 , SEEK_SET);// needed for next read from beginning of file
...
fclose(fp);
}

but you can do it without opening file:

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

struct stat buffer;
int status;

status = stat("path to file", &buffer);
if(status == 0) {
// size of file is in member buffer.st_size;
}

Is there a way to get size of a file on Windows using C?

FILE* file = fopen(path, "r"); should be FILE* file = fopen(path, "rb"); If you want an accurate size open the file in binary mode.

On Windows reading a file in text mode causes "\r\n" sequences to be converted to "\n", resulting in the apperance of fewer bytes being read than expected.

How can I get a file's size in C without using either fseek or stat?

If you can rely on the input to be a persistent file (i.e. residing on storage media), and on that file not being modified during your program's run, then you could pre-read it to the end to count the bytes in it, then rewind.

But outside of an academic exercise, the usual reason to forbid measuring the size via stat(), fseek(), and similar is that the input might not reside on storage media, so that

  1. you cannot determine its size without reading it, but also
  2. you cannot rewind it or seek within it.

The trick then is not how to determine the size in advance, but rather how to do without measuring the size in advance. There are at least two main strategies for that:

  • Don't rely on storing the whole contents in memory at once in the first place. Instead, operate on its contents as they are read, maintaining only enough in memory at any given time to do so.

  • Alternatively, adapt dynamically to the file size. There are many variations on this. For example, if you're just reading the file into a monolithic block then you can malloc() space and realloc() when you find you need more. Or you could store the contents in a linked list, allocating new list nodes as needed.

As for the approach presented in the question, there are several issues with it. It appears to be an attempt to do as I first described -- reading the file to the end to determine its size -- but

  1. It seems to assume that each read() will start at the beginning of the file, or perhaps that read() will fail if it cannot read the full file. Neither is the case. Each read() will start at the file's current position, and will leave the file positioned after the last byte transferred.

  2. Because it changes the file position, your approach will require the file to be rewound after -- via lseek(), for example. But if lseek() can be used for that purpose (and note well my previous comments with respect to files in which you cannot seek), then it would provide a much cleaner approach to measuring the file's size.

  3. You do not account for I/O errors. If one occurred then it would probably send your program into an infinite loop.

  4. Dynamic allocation is comparatively expensive, and you're doing a whole lot of it. If you want to implement the pre-reading strategy, then this would be a better implementation:

    ssize_t count_bytes(int fd) {
    ssize_t num_bytes = 0;
    char buffer[2048];
    ssize_t result;

    do {
    result = read(fd, buffer, sizeof(buffer));
    if (result < 0) {
    // handle error ...
    }
    num_bytes += result;
    while (result > 0);

    return num_bytes;
    }

How do you determine the size of a file in C?

On Unix-like systems, you can use POSIX system calls: stat on a path, or fstat on an already-open file descriptor (POSIX man page, Linux man page).

(Get a file descriptor from open(2), or fileno(FILE*) on a stdio stream).

Based on NilObject's code:

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

off_t fsize(const char *filename) {
struct stat st;

if (stat(filename, &st) == 0)
return st.st_size;

return -1;
}

Changes:

  • Made the filename argument a const char.
  • Corrected the struct stat definition, which was missing the variable name.
  • Returns -1 on error instead of 0, which would be ambiguous for an empty file. off_t is a signed type so this is possible.

If you want fsize() to print a message on error, you can use this:

#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

off_t fsize(const char *filename) {
struct stat st;

if (stat(filename, &st) == 0)
return st.st_size;

fprintf(stderr, "Cannot determine size of %s: %s\n",
filename, strerror(errno));

return -1;
}

On 32-bit systems you should compile this with the option -D_FILE_OFFSET_BITS=64, otherwise off_t will only hold values up to 2 GB. See the "Using LFS" section of Large File Support in Linux for details.

Portable way to get file size in C/C++

Using std's stream you can use:

std::ifstream ifile(....);
ifile.seekg(0, std::ios_base::end);//seek to end
//now get current position as length of file
ifile.tellg();

If you deal with write only file (std::ofstream), then methods are some another:

ofile.seekp(0, std::ios_base::end);
ofile.tellp();


Related Topics



Leave a reply



Submit