如何使用 Perl 确定磁盘上的实际文件大小?

发布于 2024-09-10 10:36:56 字数 385 浏览 7 评论 0原文

我正在扫描文件系统并希望确定磁盘上文件的分配大小。

使用 stat() 我可以获得文件大小为 ( stat(_ ) )[7],磁盘上分配的块可以从( stat(_) )[12]获取,“文件系统I/O的首选块大小”为( stat(_) )[11]

但是,如果我仅将统计列 11 和 12 相乘,则不会得到磁盘上分配的空间(在 Solaris 5.10 sparc 上)。

如何通过 Perl 中的 stat() 函数调用以编程方式获取磁盘上为文件分配的空间?

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 file from the stat() function call in Perl?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乄_柒ぐ汐 2024-09-17 10:36:56

(stat _)[11] 中公开的值是 st_blksize,即 记录

关于 I/O 操作的“最佳”单元大小的提示。该字段没有为块特殊文件或字符特殊文件定义。

这不一定是文件所在的特定文件系统的块大小,但同一手册页包含一个方便的定义:

<前><代码> blkcnt_t st_blocks; /* 分配的512字节块的数量*/

因此,您可以使用诸如“

#! /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";
}

如果您担心文件系统的块大小不是 512 的倍数,请仔细检查”

df -g <directory>

或“如果您有 root”

fstyp -v /dev/dsk/...

之类的代码对于普通文件,文件本身的大小,ie(stat _)[7],通常小于分配的所有块的总大小,因为文件系统分配整个块。

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.

草莓味的萝莉 2024-09-17 10:36:56

这是在 ZFS 文件系统上吗?我不确定它如何与 Perl 的 stat 函数调用交互,但文件的实际大小与 ZFS 中磁盘上报告的大小之间通常存在差异,具体取决于元数据和压缩。根据 perldoc -f stat 中的文档,我没有看到任何方法可以从 Perl 的 stat 中提取足够的信息来推测在 ZFS 的独特情况下磁盘上实际存在的内容。如果所有其他方法都失败了,并且您需要不惜一切代价确定磁盘上实际存在的内容,作为丑陋的最后手段,您可以简单地向 du 支付费用。

请参见此处。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文