Search code examples
clinuxwindowsporting

'st_blksize' : is not a member of 'stat' on Windows


As I want to do porting to windows from Linux. I realized that Windows and Linux API both has stat.h but with kind of differences. The problem is that Windows stat.h does not have st_blksize variable but Linux does. I does not really understand what st_blksize can do also. Can anyone help me cope with this ? How to find the equivalent of st_blksize on Windows ?


Solution

  • For the Linux struct definition go here: http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html

    The primary excerpts:

    • st_size: File size in bytes (if file is a regular file)
    • st_blksize: A filesystem-specific preferred I/O block size for this object. In some filesystem types, this may vary from file to file
    • st_blocks: Number of blocks allocated for this object

    It's pretty clear to see that st_size should equal st_blksize * st_blocks for regular files.

    For your cross platform code you're going to want to #ifdef anything that works with st_blksize or st_blocks. Or preferably you can just use st_size everywhere in your code.

    Further reading: https://groups.google.com/forum/#!topic/comp.unix.programmer/7saTJ9gRBEM

    EDIT in response to IInspectable:

    The block size on Windows should be 512, but if you need to validate, you can use the GetDriveGeometry function from here to get a DISK_GEOMETRY*.

    DISK_GEOMETRY's BytesPerSector will give you the equivalent of st_blksize.

    Note the use of GetDriveGeometry's use of CreateFileW is unnecessary for most applications. So you can probably replace it with CreateFile and adjust GetDriveGeometry to just accept a good old ASCII path.

    If you still need to get st_blocks you can obtain this from the ceiling of st_size over BytesPerSector.

    EDIT to update with respect to the Filesystem TS:

    For the typical programming application all that is needed is the size of the file. The Filesystem TS now provides a cross platform way to obtain file size in the form of file_size.

    ofstream("foo.txt") << "lorem ipsum";
    cout << experimental::filesystem::file_size("foo.txt") << endl; // Prints 11
    

    Unfortunately experimental/filesystem will not be included until GCC 5.3, however since the Filesystem TS "is directly based on boost.filesystem," experimentation in Boost may be an alternative: http://coliru.stacked-crooked.com/a/7b143609e6922774