Multiple Approaches to Get File Size in C Programming

Oct 28, 2025 · Programming · 20 views · 7.8

Keywords: C programming | file operations | file size | fseek | ftell | dynamic memory allocation

Abstract: This article comprehensively explores various methods for obtaining file sizes in C programming, with detailed analysis of the standard library approach using fseek and ftell, comparisons with POSIX stat function, and Windows-specific GetFileSize API. Through complete code examples and in-depth technical analysis, the article explains implementation principles, applicable scenarios, and performance differences, providing C developers with comprehensive file size acquisition solutions.

Importance of File Size Acquisition

In C programming, accurately obtaining file size is a fundamental yet crucial task. When loading file content into memory for processing, knowing the file size in advance helps prevent insufficient memory allocation or wastage. Particularly in dynamic memory allocation scenarios, precise file size information ensures that malloc function allocates appropriate memory space, thereby enhancing program stability and efficiency.

Standard Library Approach: fseek and ftell Combination

The C standard library provides a complete set of file operation functions, with the combination of fseek and ftell being the most commonly used method for file size acquisition. The core concept involves moving the file pointer to the end of the file and then obtaining the current pointer position to determine the file size.

#include <stdio.h>

long get_file_size(FILE *fp) {
    if (fseek(fp, 0L, SEEK_END) != 0) {
        return -1; // File positioning failed
    }
    
    long size = ftell(fp);
    if (size == -1L) {
        return -1; // Position retrieval failed
    }
    
    // Restore file pointer to starting position
    fseek(fp, 0L, SEEK_SET);
    return size;
}

In this implementation, the fseek function moves the file pointer to the end of the file. The first parameter is the file pointer, the second parameter is the offset (set to 0 indicating no offset from the specified position), and the third parameter SEEK_END indicates positioning relative to the end of the file. The ftell function returns the current file pointer position, which, since the pointer is at the end of the file, represents the total file size.

It's important to note that after using this method, the file pointer must be repositioned to the beginning of the file; otherwise, subsequent read operations cannot retrieve file content. This can be achieved using either fseek(fp, 0L, SEEK_SET) or rewind(fp).

Error Handling and Edge Cases

In practical applications, various error scenarios must be thoroughly considered. Files may not exist, lack read permissions, or file pointer operations may fail. A robust error handling mechanism should include:

#include <stdio.h>
#include <errno.h>

long safe_get_file_size(const char *filename) {
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL) {
        perror("File opening failed");
        return -1;
    }
    
    if (fseek(fp, 0, SEEK_END) != 0) {
        perror("File positioning failed");
        fclose(fp);
        return -1;
    }
    
    long size = ftell(fp);
    if (size == -1L) {
        perror("File size retrieval failed");
        fclose(fp);
        return -1;
    }
    
    rewind(fp); // Reset file pointer
    fclose(fp);
    return size;
}

POSIX System Specific Method: stat Function

In Unix/Linux systems, the stat function provides a more efficient way to obtain file information. This method can retrieve file size without actually opening the file, offering significant performance advantages.

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

long get_file_size_stat(const char *filename) {
    struct stat file_info;
    
    if (stat(filename, &file_info) == -1) {
        perror("stat function call failed");
        return -1;
    }
    
    return file_info.st_size;
}

The stat function directly reads the file's inode information, avoiding the overhead of actually opening the file. Besides file size, the stat structure contains detailed information such as file permissions, creation time, modification time, providing comprehensive data support for file management.

File Descriptor Version: fstat Function

When a file descriptor has been obtained through the open function, the fstat function can be used to retrieve file information:

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

long get_file_size_fstat(int fd) {
    struct stat file_info;
    
    if (fstat(fd, &file_info) == -1) {
        perror("fstat function call failed");
        return -1;
    }
    
    return file_info.st_size;
}

Windows Platform Specific Method

In Windows systems, the GetFileSize series of functions can be used to obtain file size:

#include <windows.h>

DWORD get_file_size_winapi(const char *filename) {
    HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 
                              NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    
    if (hFile == INVALID_HANDLE_VALUE) {
        return (DWORD)-1;
    }
    
    DWORD fileSize = GetFileSize(hFile, NULL);
    CloseHandle(hFile);
    
    return fileSize;
}

Method Comparison and Selection Recommendations

Various file size acquisition methods have their respective advantages and disadvantages:

Standard Library Method (fseek/ftell):

POSIX stat Method:

Windows GetFileSize Method:

Practical Application Example: Dynamic Memory Allocation

A typical application scenario for obtaining file size is dynamic memory allocation. The following example demonstrates how to safely read file content into dynamically allocated memory:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *read_file_into_buffer(const char *filename) {
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL) {
        return NULL;
    }
    
    // Get file size
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    rewind(fp);
    
    if (file_size <= 0) {
        fclose(fp);
        return NULL;
    }
    
    // Allocate memory (including string terminator)
    char *buffer = malloc(file_size + 1);
    if (buffer == NULL) {
        fclose(fp);
        return NULL;
    }
    
    // Read file content
    size_t bytes_read = fread(buffer, 1, file_size, fp);
    fclose(fp);
    
    if (bytes_read != file_size) {
        free(buffer);
        return NULL;
    }
    
    buffer[file_size] = '\0'; // Add string terminator
    return buffer;
}

Performance Optimization Considerations

When dealing with large files or scenarios requiring frequent file size acquisition, performance optimization becomes particularly important:

Conclusion

Obtaining file size is a fundamental operation in C language file processing. Choosing the appropriate method requires comprehensive consideration of platform compatibility, performance requirements, and code complexity. The standard library's fseek/ftell combination provides the best cross-platform compatibility, while system-specific APIs offer better performance on their respective platforms. In actual development, the most suitable implementation should be selected based on specific requirements, always incorporating robust error handling mechanisms.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.