Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning the size file without read permission c++

Tags:

c++

I am using this piece of code

long filesize (const char * filename)
{
    ifstream file (filename, ios::in|ios::binary);
    file.seekg (0, ios::end);
    return file.tellg();
}

in order to return the size of file in bytes. However i file without read permission results in returning -1. Is there any way using c++ or c to return size of the file and directories , that works even on file without read permission? I was looking for a while but fail to find solid solution.

like image 945
Dingo Avatar asked Jun 06 '16 19:06

Dingo


3 Answers

The current c++ standard library does not offer the possibility to inquire the size of a file from the file system.

In the future, when c++17 is released, the c++ standard library will have have an API for basic file system operations. Using that API, this should not require read permission to the file (but you do need permission on all parent directories in the path, of course) although, I don't think that the standard provides any guarantees about non-requirement of permissions:

return std::filesystem::file_size(filename);

Until the upcoming standard is supported by your standard library (some standard libraries already have experimental support for experimental/filesystem technical specification), you will need to resort to OS specific API or a non-standard wrapper library.

like image 162
eerorika Avatar answered Nov 09 '22 15:11

eerorika


Well, without read permission your file will be left in error state, and calling file.seekg() will result in an error state as well:

long filesize (const char * filename)
{
    ifstream file (filename, ios::in|ios::binary);
    if(file) { // Check if opening file was successful
        file.seekg (0, ios::end);
        return file.tellg();
    }
    return -1; // <<<< Indicate that an error occured
}

If the file doesn't let you open it, you can still inspect the directory structure and get informations about files using stat(). But this is platform (POSIX compliance) dependent (and of course you need access rights to read the directories content information).

like image 22
πάντα ῥεῖ Avatar answered Nov 09 '22 15:11

πάντα ῥεῖ


On a POSIX system, you can use stat.

Summary:

#include <sys/stat.h>

int stat(const char *restrict path, struct stat *restrict buf);

So, you declare a stat structure to hold the result, and pass the pointer to stat:

struct stat buf;
stat(filename, &buf);

The size (in bytes) is contained in buf.st_size.

If your standard library implementation includes <experimental/filesystem> (which should come out of experimental with C++17), you can use that instead. #include <experimental/filesystem>, and then use std::experimental::filesystem::file_size(filename) instead of your filesize function. (This also returns the size in bytes. It just calls the stat function on POSIX systems.)

For GCC, you will need to link with -lstdc++fs (see experimental::filesystem linker error).

like image 36
Nick Matteo Avatar answered Nov 09 '22 17:11

Nick Matteo