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
- you cannot determine its size without reading it, but also
- 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 andrealloc()
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
It seems to assume that each
read()
will start at the beginning of the file, or perhaps thatread()
will fail if it cannot read the full file. Neither is the case. Eachread()
will start at the file's current position, and will leave the file positioned after the last byte transferred.Because it changes the file position, your approach will require the file to be rewound after -- via
lseek()
, for example. But iflseek()
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.You do not account for I/O errors. If one occurred then it would probably send your program into an infinite loop.
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 of0
, 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
How to Receive a Lambda as Parameter by Reference
Undefined Symbols for Architecture X86_64: Compiling Problems
C++11 Type Trait to Differentiate Between Enum Class and Regular Enum
Why Can't I Inherit from Int in C++
Can Using a Lambda in Header Files Violate the Odr
Version 'Cxxabi_1.3.8' Not Found (Required by ...)
C++ How to Allocate Memory Dynamically on Stack
Linear Index Upper Triangular Matrix
Why Do Linked Lists Use Pointers Instead of Storing Nodes Inside of Nodes
Why Is Std::Vector::Operator[] 5 to 10 Times Faster Than Std::Vector::At()
Forcing Nvidia Gpu Programmatically in Optimus Laptops
What Would a Std::Map Extended Initializer List Look Like
Why Is Std::Is_Pod Deprecated in C++20
How to Use Memcpy in C++ to Copy Classes That Have No Pointers or Virtual Functions
Why Does the Size of a Class Depends on the Order of the Member Declaration? and How