2

I am trying to get size of a file that is still downloading by another process. I used the code below(which I found in here):

os.stat(filepath).st_blocks*512

However, it also return the allocated size of the file. Upon recent inspections, I discovered the accuracy of this solution depends on the OS it's working on. Currently, my OS is ubuntu 12.04 server with ext3 filesystem. Is there another way to find real file size in python?

Community
  • 1
  • 1
Hgeg
  • 545
  • 6
  • 19
  • The reason you're seeing the wrong size, is perhaps that the downloading application allocates space for the whole file at once. Unless you can interface the downloading process, I'm not sure how you'd do it? – Morten Jensen Oct 18 '12 at 11:41
  • Probably, but the thing is This method was working correctly in another distro. – Hgeg Oct 18 '12 at 12:17
  • With the same downloading application, same versions and all? – Morten Jensen Oct 18 '12 at 12:22
  • Yes. I just made a backup of my applications and installed a new OS. – Hgeg Oct 18 '12 at 14:03

3 Answers3

7

From the documentation for stat():

On some Unix systems (such as Linux), the following attributes may also be available:

  • st_blocks - number of 512-byte blocks allocated for file
  • st_blksize - filesystem blocksize
  • st_rdev - type of device if an inode device
  • st_flags - user defined flags for file

What you seem to want is st_blocks * st_blksize. Do note that this is not the actual size of the file, which is the st_size member. The number of blocks multiplies by the block size will be larger than the actual file size.


Note: When it says "st_blocks - number of 512-byte blocks allocated for file", the number 512 is actually system-dependent. The POSIX specification says

The unit for the st_blocks member of the stat structure is not defined within POSIX.1-2008. In some implementations it is 512 bytes. It may differ on a file system basis.

If the st_block attribute is available, then don't be surprised if it's some other value.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 3
    It seems that ``file_stat.st_blocks * 512`` gives the correct result, regardless of ``st_blksize``. The stat man page (https://linux.die.net/man/2/stat) also describes ``st_blksize`` simply as '"preferred" blocksize for efficient file system I/O'. – MisterMiyagi Feb 12 '18 at 10:46
  • 1
    The edit to the answer is correct but the answer starts with "What you seem to want is `st_blocks * st_blksize`". This is never correct and there's no relation between `st_blocks` and `st_blksize`. If you can assume Linux then you're assured it's in blocks of 512 but the only portable solution I'm aware of is ST_NBLOCKSIZE from Gnulib's `stat-size.h` – orip Feb 20 '20 at 09:31
1

Try

os.stat(filepath).st_size

Seems it returns what you see in "ls -l"

waitingkuo
  • 89,478
  • 28
  • 112
  • 118
0

Independently of your SO, you can access to the metadata of the file:

metadata = os.stat(path_to_file)
metadata.st_size
juankysmith
  • 11,839
  • 5
  • 37
  • 62