디스크 공간은 블록 단위로 할당되므로 디렉터리가 소비하는 실제 공간을 바이트 단위가 아닌 블록 단위로 보고하는 것이 더 정확합니까?
1,025바이트 파일이 1,024바이트 블록으로 공간이 할당된 파일 시스템에 상주하는 경우 해당 파일은 2개의 전체 블록을 차지합니다. 파일이 1,025바이트의 공간을 차지한다고 말하는 것보다 이것이 더 정확해 보입니다.
편집: 문제의 파일 시스템은 ext4, 중복 제거 없음, 압축 없음, fwiw입니다.
내 시도는 다음과 같습니다.
def getDirUsage(filepath, block_size=1024): # block_size as reported by os.statvfs()
'''
return the number of blocks consumed by a directory
'''
total_size = int(math.ceil(os.path.getsize(filepath)/block_size)) # debatable whether this should be included in the size
allfiles = os.listdir(filepath)
for f in allfiles:
p = os.path.join(filepath,f)
if os.path.isdir(p):
total_size += getDirUsage(p,block_size)
else:
total_size += int(math.ceil(os.stat(p).st_size/block_size))
return total_size
답변1
예, 블록은 물리적 디스크 사용이기 때문에 더 좋지만 다르게 가져와야 합니다.
os.stat
필드를 사용합니다 st_blocks * 512
.https://docs.python.org/2/library/os.html#os.stat
os.stat(path)
stat()
지정된 경로에서 시스템 호출과 동등한 작업을 수행합니다. (이 함수는 심볼릭 링크를 따릅니다. 심볼릭 링크 수를 계산하려면 를 사용하세요lstat()
.)일부 Unix 시스템(예: Linux)에서는 다음 속성을 사용할 수도 있습니다.
st_blocks
- 파일에 할당된 512바이트 블록 수
st_blksize
- 효율적인 파일 시스템 I/O를 위한 파일 시스템 블록 크기
st_blksize
가변적인 블록 크기나 중복 제거 기능을 갖춘 새로운 고급 파일 시스템 중 하나를 사용하지 않는 한 일반적으로 크기가 배수로 늘어나게 됩니다 . 파일 시스템 구현에 따라 파일 시스템의 중복 제거가 블록 수에 반영될 것으로 예상할 수 있지만, 이를 염두에 두면 중복 제거는 소프트/하드 링크와 비슷하지만 물리적 데이터에 대한 것입니다. FS는 블록을 모든 파일로 나눌 수 있습니까, 아니면 단일 파일에 대한 블록만 보고할 수 있습니까? 아마도 그렇지 않을 것입니다.
소프트/하드 링크도 고려해야 합니다. 현재 소프트 링크 대상의 크기를 추가하게 됩니다( lstat
이 링크를 사용해 보세요). 하드 링크를 복제하는 쉬운 방법은 블록 크기를 하드 링크 수( st_nlink
)로 나누는 것입니다. 그러면 전체 드라이브에 대해 한 번만 inode를 계산하면 됩니다. 그렇지 않으면 inode 번호를 추적해야 합니다.
학습 연습을 하는 것이 아니라면... Ouki가 언급했듯이 du
다른 사람들이 이미 이것을 고려한 것처럼 사용하십시오.
답변2
파일이 실제로 디스크에서 얼마나 많은 공간을 차지하는지 정확하게 계산하는 것은 간단하지 않습니다. 철저한 대답은 파일 크기를 다음 디스크 블록으로 반올림하는 것보다 더 복잡하기 때문입니다.
무엇에 대해:
- 하드 링크?
- 파일 시스템이 내부적으로 디스크 공간을 할당하는 이상한 방식(하프 블록 할당)이 있습니까?
- 압축 파일 시스템?
- 다음과 같은 이국적인 특징이 있습니다."데이터 중복 제거"?
모든 것을 합산하면 작업이 실제로 어떻게 작동하는지에 대한 적절한 내부 이해 없이는 작업이 거의 불가능합니다(따라서 파일에 대한 단순한 통계는 아닙니다).
시스템 도구
그러나 이를 위해 또는 "점유 블록" 옵션을 사용하여 설계된 많은 시스템 도구가 있습니다. 가장 일반적으로 사용되는 2가지 방법은 다음과 같습니다.
뒤
~에서남성
du
(FreeBSD에서 더 자세히 설명):DESCRIPTION The du utility displays the file system block usage for each file argument and for each directory in the file hierarchy rooted in each directory argument. If no file is specified, the block usage of the hierarchy rooted in the current directory is displayed.
LS-S
남성의 경우
ls
:-s, --size print the allocated size of each file, in blocks
ls
( "블록"은 실제로 실제 디스크 블록이 아닌 구식 1024바이트 블록인 것처럼 보입니다 .)
예:
$ dumpe2fs /dev/mapper/vg_centurion-lv_root |head -20 |grep ^Block
dumpe2fs 1.41.12 (17-May-2010)
Block count: 13107200
Block size: 4096
따라서 루트 파일 시스템에는 4k 블록이 있습니다.
$ ls -l
total 88
-rw-------. 1 root root 2510 Mar 20 18:00 anaconda-ks.cfg
-rw-r--r--. 1 root root 67834 Mar 20 17:59 install.log
-rw-r--r--. 1 root root 12006 Mar 20 17:57 install.log.syslog
Du와 함께:
$ du -h anaconda-ks.cfg
4.0K anaconda-ks.cfg
그리고 ls:
$ ls -ls
total 88
4 -rw-------. 1 root root 2510 Mar 20 18:00 anaconda-ks.cfg
72 -rw-r--r--. 1 root root 67834 Mar 20 17:59 install.log
12 -rw-r--r--. 1 root root 12006 Mar 20 17:57 install.log.syslog
답변3
그리고 희소 파일도 잊지 마세요.
$ dd if=/dev/null of=MEAN_FILE bs=1024k seek=1024k
0+0 Datensätze ein
0+0 Datensätze aus
0 Bytes (0 B) kopiert, 1,0298e-05 s, 0,0 kB/s
$ ls -lh MEAN_FILE
-rw-r--r-- 1 yeti yeti 1,0T Apr 3 09:44 MEAN_FILE
$ du MEAN_FILE
0 MEAN_FILE