开发者

How can I determine actual file size on disk using Perl?

开发者 https://www.devze.com 2023-01-08 02:31 出处:网络
I am scanning a file system and wish to determine the allocated size of a file on disk. Using stat() I can get the file size as( stat(_) )[7] , the blocks allocated on disk can be obtained from ( sta

I am scanning a file system and wish to determine the allocated size of a file on disk.

Using stat() I can get the file size as ( stat(_) )[7] , the blocks allocated on disk can be obtained from ( stat(_) )[12], and the "preferred block size for file system I/O" is ( stat(_) )[11].

If I merely multiply stat column 11 and 12, however, I do not get what appears to be the allocated space on disk (on Solaris 5.10 sparc).

How can I programmatically get the space allocated on disk for a f开发者_运维百科ile from the stat() function call in Perl?


The value exposed in (stat _)[11] is st_blksize, which is documented as

A hint as to the "best" unit size for I/O operations. This field is not defined for block special or character special files.

This is not necessarily the block size of the particular filesystem on which your file resides, but the same manual page contains a convenient definition:

 blkcnt_t st_blocks;   /* Number of 512 byte blocks allocated*/

So you could use code such as

#! /usr/bin/perl

use warnings;
use strict;

sub usage { "Usage: $0 file ..\n" }

die usage unless @ARGV;

foreach my $file (@ARGV) {
  my $dir = dirname $file;

  my $blocks = (stat $file)[12];
  unless (defined $blocks) {
    warn "$0: stat $file: $!\n";
    next;
  }

  print "$file - ", $blocks * 512, "\n";
}

If you're concerned that the block sizes of your filesystems aren't multiples of 512, double-check with either

df -g <directory>

or if you have root

fstyp -v /dev/dsk/...

For an ordinary file, the size of the file itself, i.e., (stat _)[7], is usually smaller than the total size of all blocks allocated because filesystems allocate whole blocks.


Is this on a ZFS filesystem? I'm not sure how it would interact with Perl's stat function call, but there is normally a disparity between the actual size of a file and what's reported on disk in ZFS, varying according to metadata and compression. Per the documentation in perldoc -f stat I don't see any way enough information could be extracted from Perl's stat to divine what's actually on disk in the unique case of ZFS. If all else fails and you need to know for certain what's actually on the disk at all costs, as an ugly last recourse you could simply shell out to du.

See here.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号